2015-04-11 21 views
6

W jaki sposób przeprowadza się nieokreślone wyszukiwanie nazwy dla nazw używanych w ciele funkcji znajomego? Rozważmy następujący kod:Funkcje znajomych i statyczne elementy danych

#include <iostream> 

void foo(); 

class A 
{ 
    friend void foo(){ std::cout << a << std::endl; } 
    static int a; 
}; 

int A::a = 10; 

int main(){ foo(); } 

DEMO

stanach standardowe w N4296::7.3.1.2/3 [namespace.memdef]:

If a friend declaration in a non-local class first declares a class, function, class template or function template the friend is a member of the innermost enclosing namespace.

Tak, spodziewałem nazwa niewykwalifikowany odnośników nie znaleźliśmy A::a, ale tak się stało. Rozmyślnie umieściłem deklarację A::a po definicji funkcji znajomego w nadziei, że nie zostanie znalezione. Jaka jest rzeczywista reguła dla niewykwalifikowanego wyszukiwania nazwiska przyjaciela?

+0

Neat pytanie; Zakładam, że * ma to związek z faktem, że jest to przyjaciel, więc może on uzyskać dostęp do członków "A" w ramach zakresu, pozostając jednocześnie w zasięgu bezpośredniego rodzica. Nigdy wcześniej tego nie rozważałem; ciekawe znalezisko. – Qix

+0

Nie ma związku między deklaracją "przyjaciela" a zmienną składową "statyczną". Nie wiem, dlaczego uważasz, że są ze sobą spokrewnieni. –

+0

@RSahu Właśnie zapytałem o niewykwalifikowane wyszukiwanie nazw dla członków danych statycznych, ponieważ nie możemy używać nie-stamatycznych członków bezpośrednio w funkcji bod przyjaciół. –

Odpowiedz

4

Odpowiedź była prosta:

N4296::3.4.1/8 [basic.lookup.unqual]:

For the members of a class X, a name used in a member function body, in a default argument, in an exceptionspecification, in the brace-or-equal-initializer of a non-static data member (9.2), or in the definition of a class member outside of the definition of X, following the member’s declarator-id31, shall be declared in one of the following ways:

[...]

(8.2) — shall be a member of class X or be a member of a base class of X (10.2),

[...]

N4296::3.4.1/9 [basic.lookup.unqual]:

Name lookup for a name used in the definition of a friend function (11.3) defined inline in the class granting friendship shall proceed as described for lookup in member function definitions.

To wszystko.

UPD:

inline jest tutaj ważne. Dlatego funkcja przyjaciół zdefiniowana poza definicją klasy nie może bezpośrednio używać statycznych elementów klasy. Na przykład, następujący kod pritns błąd czasu kompilacji:

#include <iostream> 

class A 
{ 
    static int a; 
    friend void foo(); 
}; 

int A::a = 10; 

void foo(){ std::cout << a << std::endl; } 



int main(){ foo(); } 

DEMO

+0

Cieszę się, że znalazłeś odpowiedź. :) –

Powiązane problemy