在回答this question时,我发现rvalue的重载分辨率与成员和非成员运算符之间的引用有一个有趣的区别。
给定两个非成员运算符,一个将left参数作为const传递,另一个作为非const传递,GCC 4.4.3和MSVC2010在使用rvalue调用时选择const版本。
但是,给定两个成员运算符,一个const和一个非const,两个编译器都选择非const版本。
我认为两个编译器都遵守这个标准,所以我很好奇为什么成员和非成员之间的const重载决议之间存在这种差异。请赐教:))
以下是一些代码来说明差异:
#include <iostream>
class C {
public:
C(int i) { }
/*
C operator<<(C const &rhs) {
std::cout << "member non-const" << std::endl;
return *this;
}
C operator<<(C const &rhs) const {
std::cout << "member const" << std::endl;
return *this;
}
//*/
};
C operator<<(C &lhs, C const &rhs) {
std::cout << "non-member non-const" << std::endl;
return lhs;
}
C operator<<(C const &lhs, C const &rhs) {
std::cout << "non-member const" << std::endl;
return lhs;
}
int main() {
// Will print:
// "non-member const" when member operators are commented out
// "member non-const" when members are uncommented
C(5) << 6;
}
答案 0 :(得分:2)
Rvalues无法绑定到引用到非const,因此只有free函数的reference-to-const重载才可行:operator<<(C(5), 6);
。
这不适用于成员运算符,它只是C(5).operator<<(6)
,而C
- 对象不是函数参数。您必须说static_cast<const C &>(C(5)) << 6
才能获得const版本,因为this
的常量可区分两个成员运算符重载。
在成员函数和自由函数运算符都存在的情况下,成员函数是首选,因此将所有这些放在一起就可以解释观察到的行为。