N3337、「ワーキング ドラフト、プログラミング言語 C++ の標準」では、13.3.1.2 節の次の例を示しています。10:
struct A { };
void operator + (A, A);
struct B {
void operator + (B);
void f ();
};
A a;
void B::f() {
operator+ (a,a); // error: global operator hidden by member
a + a; // OK: calls global operator+
}
ただし、これは単なるメモです。
注: 次の例に示すように、式内の演算子の検索規則は、関数呼び出し内の演算子関数名の検索規則とは異なります。
私の質問は、標準のどこで、これが起こらなければならないことであると言っているのですか?
私が知る限り、条項13.3.1.2によると、p。2、演算子式は演算子関数呼び出しに変換されます。では、上記の例では、なぜ、どのように違いがあるのでしょうか?
編集:
問題を調べたところ、p を見落としていたのではないかと思います。3 と p.6 の同じ節で、演算子を検索するときにグローバル候補とメンバー候補が同等に考慮されると述べられています (したがって、注記にあるように、検索ルールは異なります)。ただし、この件に関する私の調査は、GCC 4.8 と Clang で同じようにコンパイルされる次の例に端を発しています。
struct X {}; struct Y {};
void operator+(X, X) { }
void operator+(X, Y) { }
void test() {
void operator+(X, X);
X x; Y y;
x + x; // OK
x + y; // OK
operator+(x, y); // error
operator+(x, x); // OK
}
演算子関数が直接呼び出された場合にブロック スコープ宣言によるシャドーイングが発生するのに、演算子式によって呼び出された場合には発生しないのはなぜですか?
GCC からのエラーは次のとおりです。
operators-main-ss.cpp: In function ‘void test()’:
operators-main-ss.cpp:13:17: error: could not convert ‘y’ from ‘Y’ to ‘X’
operator+(x, y); // error
^
そしてここでClangから:
operators-main-ss.cpp:13:16: error: no viable conversion from 'Y' to 'X'
operator+(x, y); // error
^
operators-main-ss.cpp:1:8: note: candidate constructor (the implicit copy constructor) not viable: no
known conversion from 'Y' to 'const X &' for 1st argument;
struct X {}; struct Y {};
^
operators-main-ss.cpp:7:22: note: passing argument to parameter here
void operator+(X, X);
^
あるケースではブロック宣言がグローバル名をシャドーし、他のケースではシャドーしないコンパイラは正しいですか?