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

Mar*_* Ba 6 c++ containers c++14

要支持异构键查找,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");
    }
}
Run Code Online (Sandbox Code Playgroud)

另请参阅:https ://www.cppstories.com/2021/heterogeneous-access-cpp20/了解说明。

从这个链接和链接的问题(以及N3657)中,给出了一些关于为什么选择加入的分散原因。由于我必须进行相当多的滚动操作,并且没有找到简洁的原因总结,因此我想在这里整理一个每个初级开发人员都能理解的总结,例如

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

;-)

Mar*_* Ba 2

如果std::map会简单地默默支持这一点,也就是说如果std::map<KeyT, ValT>会支持find(LookupT)“任何兼容”类型,那么:

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

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

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

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