考虑这个问题,它是关于以下代码无法编译的问题:
std::vector<int> a, b;
std::cout << (std::ref(a) < std::ref(b));
这段代码无法编译,因为vector
的比较运算符是非成员函数模板,而隐式转换不被允许考虑。然而,如果将这些运算符改为非成员非模板的friend
函数:
template <class T, class Allocator = std::allocator<T>>
class vector {
// ...
friend bool operator<(const vector& lhs, const vector& rhs) {
// impl details
}
};
那么,如果采用这个版本的operator<
,ADL将会找到它并选择它作为最佳可行重载,原始示例将会编译。鉴于此,我们是否有理由更喜欢当前所拥有的非成员函数模板,或者应该将其视为标准中的缺陷?
operator<<
和流也存在类似的问题:这确实引起了一些问题。我可以编写一个template<class C> operator<<(std::basic_ostream<C>&,std::basic_string<C>&)
而不依赖于两者之一的更多声明。"Koenig 操作符" 至少需要其中一个(哪个?), 它是否需要两个都有呢?(这是离题的,因为它涉及到两种类型的操作符,而不是像上面那样只有一个)。 - Yakk - Adam Nevraumontstd::ref(a) < std::ref(b)
。对我来说,这似乎是违反直觉的,因为ref
返回的是完全独立的类类型。 - Columboint
。此外,我不知道为什么你会做很多事情 - 这并不意味着语言不允许它。此外,这将使您的带有operator std::string()
的类可以与string
可比较的东西进行比较。 - Barryoperator()
的支持,通过向reference_wrapper
添加一个包装器运算符,就可以支持ref(a) < ref(b)
。此外,我不确定依赖隐式转换来应用运算符是否是一个好主意。 - dyp