2010-12-09 3 views
4

Что означает следующее (особенно выделенная часть)? Почему выражение «f (a)» рассматривается как «литое выражение»? ..Функция друга

C++ 03 $ 3.4/3- «Поиск для неквалифицированного имени , используемого в качестве постфикса-выражения вызова функции описан в разделе 3.4.2 [Примечание: для целей определения (в ходе синтаксического разбора) выражение является ли постфикс-выражением для вызова функции , обычное название применяются правила подстановки. правила в 3.4.2 не имеет влияния на синтаксической интерпретации выражения. Например,

typedef int f; 
struct A { 
friend void f(A &); 
operator int(); 
void g(A a) { 
f(a); 
} 
}; 

Выражение f (a) является выражением, эквивалентным int (a). Поскольку выражение не является вызовом функции, зависящий от аргумента поиск имени (3.4.2) не применяется, а функция друга f не найдена. ]»

Любые мысли?

ответ

1

Это означает, что анализатор сначала определяет выражение перед скобками, является ли идентификатор или постфикса выражение. В этом случае он видит 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.

+1

uncommenting # 2 отключил бы поиск koenig в соответствии с правилами C++ 0x, хотя (некоторые компиляторы используют эти правила даже в режиме C++ 03). Таким образом, он будет компилироваться как вызов функции, но как вызов локально объявленной функции и приведет к ошибке. – 2010-12-09 13:27:54