为什么异构std::*映射查找在C++中选择加入



要支持std::map的异构密钥查找,必须比过去更详细:(取自如何的问题)

int main()
{
{
puts("The C++11 way makes a copy...");
std::map<std_string, int> m;
auto it = m.find("Olaf");
}
{
puts("The C++14 way doesn't...");
std::map<std_string, int, std::less<>> m;
auto it = m.find("Olaf");
}
}

另请参阅:https://www.cppstories.com/2021/heterogeneous-access-cpp20/以获得解释。

从这个链接和相关问题(以及N3657)中,有一些零散的原因说明了为什么选择加入。由于我必须进行一些滚动,并且没有找到原因的简洁摘要,我想在这里总结一下每个初级开发人员都能理解的

为什么愚蠢的C++让我写额外的std::less<>??!为什么它不允许与我们一直使用的默认类型进行透明的异构比较?

;-)

地图模板有一个默认的比较

template<
class Key,
class T,
class Compare = std::less<Key>,
class Allocator = std::allocator<std::pair<const Key, T> >
> class map;

假设您想要一个map<my_type, int>,并通过专门化std::less<my_type>来启用它(默认情况下使用它)。

那么C++14就不能直接使用非专用的std::less<>了。所以你必须明确要求!

如果std::map只是默默地支持这一点,也就是说,如果std::map<KeyT, ValT>支持find(LookupT);任何兼容的";然后键入:

  • 关于此事的下降页面引用了doubleint之间的隐含比较,这将是一个麻烦:

隐式支持异构查找可能是危险的,因为转换后可能不会维护值之间的关系。例如,1.0 < 1.1,但static_cast<int>(1.0) == static_cast<int>(1.1)。因此,使用double查找std::set<int>中的值可能会导致不正确的结果。

  • 性能(!)-类型不支持异构比较的旧代码将开始运行更慢:dyp写道:

考虑对于某些类型stupid_string只存在一个转换构造函数来自char const*而不是比较运算符operator<(stupid_string const&, char const*)、仅来自operator<(stupid_string const&, stupid_string const&)。由于std::less<>((将))转发到比较运算符,因此每次比较都将创建一个新的stulid_string。

(而不是只在std::find的调用站点上创建一次额外的比较对象)

最新更新