2015-04-11 6 views
6

In che modo viene eseguita la ricerca del nome non qualificato per i nomi che utilizzano all'interno del corpo della funzione dell'amico? Consideriamo il seguente codice:Funzioni di amici e membri di dati statici

#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

La norma nella 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.

Quindi, mi aspettavo di ricerca del nome non qualificato non ha trovato A::a, ma lo ha fatto. Ho deliberatamente inserito la dichiarazione A::a dopo la definizione della funzione dell'amico nella speranza che non venga trovata. Qual è la regola effettiva per la ricerca del nome non qualificato del tuo amico?

+0

domanda Neat; Sto * assumendo * che ha a che fare con il fatto che sia un amico, quindi è in grado di accedere ai membri dell'ambito di 'A' mentre è ancora inserito nell'oggetto del genitore diretto. Non l'ho mai considerato prima; scoperta interessante. – Qix

+0

Non esiste alcuna relazione tra la dichiarazione 'friend' e la variabile membro' static'. Non so perché pensi che siano imparentati. –

+0

@RSahu Ho appena chiesto informazioni sulla ricerca di nomi non qualificati per i membri di dati stattici. Non possiamo usare direttamente membri non ststaic all'interno della funzione di amici. –

risposta

4

la risposta era abbastanza semplice:

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.

Questo è tutto.

UPD:

Inlining è importante qui. Ecco perché la funzione friend definita al di fuori della definizione della classe non può utilizzare direttamente membri statici della classe. Per esempio, il codice seguente pritns errore di tempo di compilazione:

#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

Sono felice che tu abbia trovato la risposta. :) –