【发布时间】:2015-07-27 17:09:24
【问题描述】:
考虑this question,这与以下代码未编译有关:
std::vector<int> a, b;
std::cout << (std::ref(a) < std::ref(b));
它无法编译,因为vector 的向量comparison operators 是非成员函数模板,并且不允许考虑隐式转换。但是,如果将运算符改为非成员非模板,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>&)without 取决于两个(任何一个)的前向声明。 “Koenig 操作员”至少需要其中一个(哪个?),它需要两者吗? (这是相切的,因为它是关于两种类型的运算符,而不是像上面那样) -
我不明白你为什么要写
std::ref(a) < std::ref(b)。对我来说这似乎有悖常理,因为ref返回一个完全独立的类类型。 -
@Columbo 它适用于
ints。此外,我不知道你为什么会做很多事情——并不意味着语言不允许这样做。此外,这将使您的班级与operator std::string()进行比较与strings 比较的事物。 -
正如我在this related question 上评论的那样,操作员通常不需要特权访问。添加对
ref(a) < ref(b)的支持与对operator()的支持类似,方法是向reference_wrapper添加包装运算符。此外,我还不清楚依赖隐式转换来应用运算符是否是个好主意。
标签: c++ templates operator-overloading language-lawyer