STD :: String应该专门使用STD ::支持异质查找的支持吗?
能够在带有的容器中查找
://www.cppstories.com/2021/heterogeneous-access-cpp20/“ rel =“ nofollow noreferrer”>好东西。请参阅:避免使用std :: map :: find() 和 https://www.cppstories.com/2021/2021/heterogeneous-eterogenous-access-access-access-cpppps-cpp20/ 和... char*
,而无需创建临时字符串对象,而无需创建
有原因为什么C ++为什么无法为任何类型的 t
用作关键类型的任何类型启用。
因此,与C ++ 20/23起,我们将剩下:
int main()
{
{
// Slow, constructs temporary
std::map<std_string, int> m;
auto it = m.find("Olaf");
}
{
// "Fast" does not need to construct temporary
std::map<std_string, int, std::less<>> m;
auto it = m.find("Olaf");
}
}
但是 - 我想知道为什么 std :: String
不会自动选择通过为 std :: Less&lt; std :: string&gt;
提供(部分?)专业?是否尚未指定这一点,或者是否有任何合法原因为什么 std :: string
(或者 std :: basic_string&lt; ...&gt;
)无法执行此操作?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我认为主要原因是没有人提出它。魔术没有任何事情发生,必须由某人提出,然后审查和批准。如果提案步骤没有发生,什么都不会改变。
但是,应该注意的是,制作
std :: Less&lt; std :: string&gt;
透明是对类型的打破变化,例如:此类直接与
std :::字符串
或首先转换为std :: String
然后进行比较。今天,将此类的实例传递到
map&lt; string,int&gt; :: find(const string&amp;)
将隐式转换为std :: String
,因此请使用m_str1
。但是,如果std :: Less&lt; std :: string&gt;
是透明的,则将使用m_str2
进行比较。那会改变行为。可以说,这堂课很愚蠢,值得打破。由于添加
&lt; =&gt;
语言对与这种奇怪行为的比较不一致的比较要少得多。但是,即使乍看之下,即使破裂的代码看起来愚蠢,也总是需要仔细考虑打破变化。可以制作
std :: Less&lt; std :: string&gt;
能够直接与 Justconst char*
和进行比较std :: string_view
没有转换(对于操作员&lt;
),例如,这也可能是一个破坏的变化。可转换为
std :: String
和const char*
(或std :: String
和std :: string_view
string_view )的类型/code>)现在将无法传递给std :: Less&lt; std :: string&gt;
,因为它会变得模棱两可。这可以解决,例如,这实际上无济于事。因为此专业化并未定义
is_transparent
成员(因为它不完全透明,因为它仅接受三种类型,而不是std :: string
),容器不会定义采用任意密钥的其他功能模板。因此,额外的sill&lt; string&gt; :: operator()
Overloads将不会使用,并且您仍然会转换为std :: String
查找(“ OLAF”)
。对不起。
I think the primary reason is that nobody proposed it. Nothing happens by magic, it has to be proposed by somebody and then reviewed and approved. If the proposal step doesn't happen, nothing will change.
However, it should be noted that making
std::less<std::string>
transparent would be a breaking change for types like:This class behaves differently when compared directly to a
std::string
or when converted tostd::string
first and then compared.Today, passing an instance of this class to
map<string, int>::find(const string&)
would implicitly convert tostd::string
and so usem_str1
. But ifstd::less<std::string>
was transparent, it would compare usingm_str2
. That would change behaviour.Arguably, this class is stupid and deserves to break. Since the addition of
<=>
the language is much less forgiving of inconsistent comparisons with this kind of odd behaviour. But breaking changes always need to be considered carefully, even if the code that would break looks stupid at first glance.It would be possible to make
std::less<std::string>
able to compare directly to justconst char*
andstd::string_view
without conversions (which is already true foroperator<
), e.g.But this could also be a breaking change. A type that is convertible to
std::string
andconst char*
(orstd::string
andstd::string_view
) would now be unable to be passed tostd::less<std::string>
because it would become ambiguous. That can be solved, e.g.But this wouldn't actually help. Because this specialization doesn't define the
is_transparent
member (because it's not fully transparent, because it only accepts three types, not anything comparable withstd::string
), the associative containers would not define the additional function templates that take an arbitrary key. And so the extraless<string>::operator()
overloads wouldn't be used, and you'd still get a conversion tostd::string
when you dofind("Olaf")
.Sorry.