为什么不为' at '和' operator[] '实现异构比较查找
Why heterogeneous comparison lookup is not implemented for `at` and `operator []`?
由于c++ 14 (N3657)中的关联容器的成员函数模板find
、count
、lower_bound
、upper_bound
和equal_range
支持异构比较查找,而at
和operator[]
没有这些等价的成员函数模板。为什么呢?
的例子:
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
元素x
和key_type
元素y
当且仅当 key_type(x) < y
时,应该有x < y
的要求,因为否则语义将是无意义的(就像它将是无意义的,例如让operator<
返回基于随机源的值)。
不幸的是,c++的模板机制既极其复杂又极其脆弱,只有在真正必要的时候才将operator[]
转换为key_type
可能比看起来要复杂得多。
然而,这种机制是c++社区决定谴责自己用于元编程的,除非有人设法只使用它来获得一个体面的实现,否则这个合理的要求可能不会出现在标准中(在过去,标准要求的东西定义模糊,或者基本上不可能实现,比如模板导出,这并不有趣)。
相关文章:
- 在C++中,如何创建包含可变模板对象的异构向量?
- 创建异构顶点数据数组的可移植方法
- std::variant vs指向C++中异构容器基类的指针
- C++中的集合(异构类型的数组)
- 从异构列表中提取数据
- Push_back一组(异构)向量的实现
- 如何在 CRTP 中实现析构函数?
- 使用 std::vector<char> 作为异构记录的存储是否安全?
- 是否可以使用 std::vector<std::any> vec;这将导致异构数据类型
- 异构容器查找 C++98
- 编译时排序的异构元组
- 异构初始化列表
- 派生实例不是指针时的基类的异构容器
- 使用shared_ptr时需要实现析构函数、复制构造函数、赋值运算符
- 顺序异构函数执行器
- 我们可以使用异构查找比较器对 STL 关联容器执行"partial-match"搜索吗?
- 异构作业处理器的并行化
- 如何解析没有前置标记的异构列表
- 从Bloch的Effective Java in C++实现类型安全的异构容器(VS2010)
- 为什么不为' at '和' operator[] '实现异构比较查找