考虑这个问题,这是关于以下不编译的代码:
std::vector<int> a, b;
std::cout << (std::ref(a) < std::ref(b));
Run Code Online (Sandbox Code Playgroud)
它不会编译,因为向量比较运算的vector都是非成员函数模板,隐式转换是不允许考虑.但是,如果运算符被写为非成员非模板,则friend函数:
template <class T, class Allocator = std::allocator<T>>
class vector {
// ...
friend bool operator<(const vector& lhs, const vector& rhs) {
// impl details
}
};
Run Code Online (Sandbox Code Playgroud)
那么这个版本operator<将由ADL找到并被选为最佳可行的重载,并且原始示例将被编译.鉴于此,是否有理由选择我们目前拥有的非成员函数模板,还是应该将其视为标准中的缺陷?
使用以下代码可以清楚地解决该问题:
#include <functional>
#include <iostream>
#include <vector>
int main() {
//std::vector<int> a, b;
int a = 0, b = 0;
auto refa = std::ref(a);
auto refb = std::ref(b);
std::cout << (refa < refb) << '\n';
return 0;
}
Run Code Online (Sandbox Code Playgroud)
如果我使用注释std::vector<int> a, b;而不是int a = 0, b = 0;,则代码不会在GCC 5.1,clang 3.6或MSVC'13中的任何一个上编译.在我看来,std::reference_wrapper<std::vector<int>>可以隐式转换std::vector<int>&为LessThanComparable,因此它应该是LessThanComparable本身.有人可以向我解释一下吗?
c++ language-lawyer implicit-conversion c++11 reference-wrapper
无序关联容器unordered_set,unordered_map等没有一个小于运算符operator<,既不是成员函数也不是一个免费的功能.为什么?less两者都没有专业化.SGI STL的hash_*类型也缺乏此功能.
如果我们排除底层类型的概念,所有容器类型都满足常规类型的要求,例如Stepanov&McJones 的编程元素.唯一的例外是缺乏的无序关联类型operator<.
我无法想出一个与给定的相等定义一致的运算符的有效实现,那么效率可能是什么原因呢?另一方面,operator==对于无序关联容器,在某些情况下需要重新散列一个容器的每个元素并在另一个容器中查找 - O(N)平均值,但最坏情况为O(N²).