2017-01-20 7 views
9

VS2015 и clang скомпилируйте этот код, но g++ rejects it.VS2015 и clang компилируют этот код, но g ++ отклоняет его. Какой из них правильный?

namespace A { 
    struct B { 
     friend void f(); 
    }; 
} 
void A::f() {} 

int main(){ 
} 

Я думаю, что г ++ прав из-за этого Отметка в 7.3.1.2/3:

Если друг декларация в нелокальной классе первым объявляет класс, функцию, шаблон класса или шаблона функции Друг является членом самого внутреннего пространства имен. Объявление друга не само по себе делает имя видимым для неквалифицированного поиска ([basic.lookup.unqual]) или квалифицированный поиск ([basic.lookup.qual]). [Примечание: Имя друга будет отображаться в его пространстве имен, если в пространстве имен (0) или предоставляется определение соответствия после определения класса, предоставляющего дружбу). - end note] Если вызывается функция или функция функции друга , ее имя может быть найдено по имени, которое рассматривает функции из пространств имен и классы , связанные с типами аргументов функции ([basic.lookup.argdep ]). Если имя в объявлении друга равно , ни квалифицированный, ни идентификатор шаблона, а декларация не являются функцией или спецификатором разработанного типа, поиск для определения того, был ли ранее объявлен объект , не учитывает какие-либо области за пределами самое внутреннее пространство имен. [Примечание. Другие формы объявлений объявлений не могут объявить новый член самого внутреннего , охватывающего пространство имен и, следовательно, следовать обычным правилам поиска. - конец примечание]

+1

относящийся: http://stackoverflow.com/questions/24600050/clang-a-friend-function-defined-within-a-class – NathanOliver

ответ

6

Эта часть вашего предложения более точно, чем в примечании вы подчеркнули:

Декларация друга само по себе не делает имя видимым для неквалифицированного поиска ([basic.lookup .unqual]) или квалифицированный поиск ([basic.lookup.qual]).

Ваше определение зависит от квалифицированного поиска, чтобы найти функцию, уже объявленную внутри пространства имен. Но имя не видно для квалифицированного поиска. Этот код должен быть отклонен.

Вот похожее правило, находится в secion 8.3 [dcl.meaning]:

Когда описатель-идентификатор квалифицирован, декларация будет относиться к ранее заявленному члену класса или пространства имен, к которому Quali фи эр относится (или , в случае пространства имен, элемента встроенного набора пространств имен этого пространства имен) или его специализации; член не должен просто вводиться с помощью объявления-декларации в области класса или пространства имен, назначаемого идентификатором-вложенным именем идентификатора-декларатора.

 Смежные вопросы

  • Нет связанных вопросов^_^