下面的SSCCE演示了这种情况:
#include <iostream>
struct ostr {
std::ostream& s;
template<class T>
ostr& operator<<(const T& x) { s << x; return *this; }
};
struct xy {
double x, y;
};
template<class Stream>
Stream& operator<<(Stream& s, const xy& x) {
s << "[" << x.x << ", " << x.y << "]";
return s;
}
int main() {
ostr os{std::cout};
xy x{4, 5};
os << "Value is: " << x <<"\n";
}
在添加了`ctor`到`ostr`之前,该项目编译正常。我使用了几个编译器(`gcc 4.5`,`4.6`,`4.7`,`4.8`和`clang 3.3`)对这个SSCCE进行了检查,并且它们都可以在没有任何警告的情况下进行编译(使用`-Wall -Wextra -pedantic`)。所有编译器都设置为C++11/C++0x标准。 在`ostr`中添加`ctor`后,即使在`MSVC 2012`和`2010`上也可以编译成功。
将两个`operator<<`都变成非成员函数会在所有编译器中表现出模棱两可的结果(如预期所示)。
在查看标准草案(`N3242`和`N3690`)之后,我未能找到任何使成员函数/运算符优于非成员函数/运算符的内容。
因此,我无法证明`clang-3.4`是错误的,我想知道谁是正确的。 因此,我的问题是:
- 这段代码有效吗?成员运算符/函数应该比非成员运算符/函数更匹配,这是`clang-3.4`的一个错误吗?
- 或者所有其他编译器都是错的/太宽容了?