функция друга - PullRequest
       9

функция друга

4 голосов
/ 09 декабря 2010

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

C ++ 03 $ 3.4. / 3- «Поиск неквалифицированного имени, используемого в качестве выражения postfix для выражениявызов функции описан в 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 Ответ

1 голос
/ 09 декабря 2010

Это означает, что синтаксический анализатор сначала определяет, является ли выражение перед круглыми скобками id или postfix-expression .В этом случае он видит f, а ближайший f определен typedef int f - поэтому он приходит к выводу, что выражение интерпретируется как int(a), и поиск Кенига не выполняется.

Давайте этот код(попробуйте онлайн: 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, она была бы интерпретирована как вызов функции, и поиск Кенига нашел быправильная перегрузка (см. строку #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() и завершится ошибкой при слишком большом количестве аргументов.был введен решением вопрос 218 .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...