Это означает, что анализатор сначала определяет выражение перед скобками, является ли идентификатор или постфикса выражение. В этом случае он видит f
, а ближайший f
определяется в typedef int f
- поэтому он заключает выражение интерпретируется как int(a)
и не поиск Koenig не выполняется
Давайте есть этот код (для вас попробовать онлайн: http://ideone.com/clone/eRKvP)
.
typedef int f;
namespace x {
struct A {
friend void f(A &);
//friend void f(); // # 1
operator int();
void g(A a) {
//void f(); // # 2
(void)f(a); // # 3
}
};
}
Если бы вы объявили (несвязанную) функцию f
видимой из g
, это будет расценено как вызов функции и Koenig поиск будет найти правильную перегрузку (см линии #2
).
Приятель декларация f
не следует применять здесь, потому что
11,4/1: ... Имя друга не в области видимости класса,
Однако, что меня беспокоит, заключается в том, что раскомментирование #1
делает компилятор (gcc в этом случае) также вызовом x::f(A&)
. Не знаю, почему. [В компиляторе Comeau Online он работает как ожидалось (например, #1
не влияет на строку #3
). Последняя бета-версия имеет проблемы при компиляции этого кода, хотя]
PS:. Как отметил LITB, правила в C++ 0x немного отличаются:
3.4.2/3:
Пусть X - набор поиска, созданный неквалифицированным поиском (3.4.1), и пусть Y будет набор поиска, созданный аргументом зависимым поиском (определяется следующим образом). Если X содержит
- декларацию члена класса или
- объявления функции блока-сферу, которая не является использованием декларации, или
- свидетельство того, что не является ни функцией или функциональный шаблон
тогда Y пуст. В противном случае Y является набором деклараций найдены в пространствах имен, связанных с
Смелого элемента сделает компилятор рассматривать только void f()
и не слишком много аргументов.
похоже, что было введено разрешением issue 218.
uncommenting # 2 отключил бы поиск koenig в соответствии с правилами C++ 0x, хотя (некоторые компиляторы используют эти правила даже в режиме C++ 03). Таким образом, он будет компилироваться как вызов функции, но как вызов локально объявленной функции и приведет к ошибке. – 2010-12-09 13:27:54