为什么不为' at '和' operator[] '实现异构比较查找

Why heterogeneous comparison lookup is not implemented for `at` and `operator []`?

本文关键字:实现 异构 比较 查找 at 为什么不 operator      更新时间:2023-10-16

由于c++ 14 (N3657)中的关联容器的成员函数模板findcountlower_boundupper_boundequal_range支持异构比较查找,而atoperator[]没有这些等价的成员函数模板。为什么呢?

的例子:

std::map<std::string, int, std::less<>> m;
// ...
auto it = m.find("foo"); // does not construct an std::string
auto& v = m.at("foo"); // construct an std::string

原则上没有逻辑上的原因。例如,对于operator[],合理的语义可以是

  • 如果传递的值与key_type可比较,则使用它进行搜索,并仅在需要时转换为key_type(即,如果没有找到该元素,并且容器既不是const,也不是使用const引用访问)。
  • 如果在传递类型之前不能转换为key_type,则使用operator[]不应该编译(就像现在发生的那样)
  • 如果传递的类型不能与key_type进行比较,但可以转换为key_type,那么应该立即创建一个临时的来进行搜索和插入(就像现在一样)。

当然,T元素xkey_type元素y 当且仅当 key_type(x) < y时,应该有x < y的要求,因为否则语义将是无意义的(就像它将是无意义的,例如让operator<返回基于随机源的值)。

不幸的是,c++的模板机制既极其复杂又极其脆弱,只有在真正必要的时候才将operator[]转换为key_type可能比看起来要复杂得多。

然而,这种机制是c++社区决定谴责自己用于元编程的,除非有人设法只使用它来获得一个体面的实现,否则这个合理的要求可能不会出现在标准中(在过去,标准要求的东西定义模糊,或者基本上不可能实现,比如模板导出,这并不有趣)。