Правила поиска операторов в C ++ 11
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, с. 2 операторные выражения преобразуются в вызовы операторских функций. Так почему и как должна быть разница в приведенном выше примере?
Редактировать:После изучения проблемы, я думаю, что я мог упустить из виду р. 3 и с.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);
^
Правильны ли компиляторы, чтобы объявление блока скрывало глобальное имя в одном случае, а не в другом?