N3337, "Рабочий проект, стандарт для языка программирования С++", приведен ниже в разделе 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 и 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
^
И вот от Клана:
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);
^
Правильны ли компиляторы, чтобы объявление блока отображало глобальное имя в одном случае, а не другое?