为什么`at`和`operator []`没有实现异构比较查找?

时间:2015-09-02 17:01:08

标签: c++ c++14

由于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

1 个答案:

答案 0 :(得分:5)

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

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

当然,应该要求x < y元素Tx元素key_type y当且仅当 key_type(x) < y因为否则语义是无意义的(例如让operator<根据随机来源返回值会是无意义的。)

不幸的是,C ++模板机制同时非常复杂且非常弱,并且只有在真正需要的情况下才能实现key_type operator[]的转换,可能比看起来更复杂。

然而,这个机制是C ++社区决定谴责自己用于元编程的东西,直到有人设法仅使用它来获得一个体面的实现,这个合理的要求可能不会在标准中(在过去它碰巧标准规定了模糊定义和/或基本上不可能像模板导出那样实现的东西,而且它并不好笑。