2017-01-20 46 views
9

VS2015 i clang skompiluj ten kod, ale g++ rejects it.VS2015 i clang kompilują ten kod, ale g ++ go odrzuca. Który jest prawidłowy?

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

int main(){ 
} 

myślę g ++ ma rację, ponieważ od tej nocie w 7.3.1.2/3:

Jeżeli deklaracja przyjaciel w nielokalnego klasy pierwszej deklaruje klasę, funkcji, klasa szablon lub szablon funkcji przyjaciel jest członkiem najgłębiej otaczającej przestrzeni nazw. Deklaracja przyjaciela sama w sobie nie powoduje, że nazwa jest widoczna dla niewykwalifikowanego wyszukiwania ([basic.lookup.unqual]) lub kwalifikowanego wyszukiwania ([basic.lookup.qual]). [Uwaga: [Imię i nazwisko przyjaciela będzie widoczne w jego przestrzeni nazw, jeśli deklaracja dopasowania zgodna z znajduje się w obszarze nazw (przed lub po po uzyskaniu przyjaźni w klasie). - nota końcowa] Jeśli wywoływana jest funkcja lub szablon funkcji znajomego, jego nazwa może być znaleziona przez wyszukiwanie nazw, które uwzględnia funkcje z przestrzeni nazw i klas powiązanych z typami argumentów funkcji ([basic.lookup.argdep ]). Jeśli nazwa w deklaracji znajomego to: ani kwalifikacja, ani identyfikator szablonu, a deklaracja nie jest funkcją lub specyfikatorem typu opracowanego, wyszukiwanie w celu ustalenia, czy jednostka została wcześniej zadeklarowana, nie uwzględnia żadnych zakresów zewnętrznych poza zasięgiem . najgłębszy otaczający obszar nazw. [Uwaga: Inne formy deklaracji znajomych nie mogą zadeklarować nowego członka najgłębszej przestrzeni nazw i tym samym przestrzegać zwykłych reguł wyszukiwania. - koniec uwaga]

+1

powiązane: http://stackoverflow.com/questions/24600050/clang-a-friend-function-defined-winin--class – NathanOliver

Odpowiedz

6

Ta część Twojej odpowiedzi jest bardziej ostateczne niż noty ty podkreślił:

Deklaracja przyjaciel samo w sobie nie sprawi, że nazwa widoczna dla niewykwalifikowanego odnośnika ([basic.lookup .unqual]) lub kwalifikowanego wyszukiwania ([basic.lookup.qual]).

Twoja definicja opiera się na wyszukiwaniu kwalifikowanym, aby znaleźć funkcję zadeklarowaną w przestrzeni nazw. Ale nazwa nie jest widoczna dla kwalifikowanego wyszukiwania. Ten kod powinien zostać odrzucony.

Oto powiązany reguła, znalezionych w secion 8,3 [dcl.meaning]:

Gdy declarator-id jest kwalifikowana, deklaracja odnosi się do wcześniej zadeklarowanej członek klasy lub przestrzeni nazw, do których kwalifikacje fi er odnosi (lub , w przypadku przestrzeni nazw, elementu zbioru przestrzeni nazw tej przestrzeni nazw) lub specjalizacji; członek nie zostanie jedynie wprowadzony przez deklarację użycia w zakresie klasy lub przestrzeni nazw wyznaczonej przez specyfikator nazwy zagnieżdżonej identyfikatora-deklaratora.