2015-04-11 4 views
6

Wie wird die Suche nach nicht qualifizierten Namen für Namen ausgeführt, die im Funktionsblock des Freundes verwendet werden? Lassen Sie sich den folgenden Code betrachten:Freundesfunktionen und statische Datenelemente

#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

Die Standard-Staaten in den 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.

Also, ich nicht qualifizierte Namen-Suche nicht zu erwarten, A::a das finden, aber es tat. Ich habe absichtlich die A::a Erklärung nach der Funktionsdefinition des Freundes in der Hoffnung gestellt, dass es nicht gefunden würde. Was ist die eigentliche Regel für die Suche nach einem nicht qualifizierten Namen eines Freundes?

+0

Ordentlich Frage; Ich nehme an, dass es mit der Tatsache zu tun hat, dass es ein Freund ist, also kann es auf in-scope-Mitglieder von "A" zugreifen, während es immer noch im direkten Elternbereich ist. Ich habe das nie vorher in Betracht gezogen. interessanter Fund – Qix

+0

Es besteht keine Beziehung zwischen der 'friend'-Deklaration und der' static' Membervariable. Ich weiß nicht, warum du denkst, dass sie verwandt sind. –

+0

@RSahu Ich fragte nur nach unqualifizierten Namenssuche für statische Datenmitglieder weil wir nicht-ststaic Mitglieder innerhalb der Funktion bod der Freunde direkt verwenden können. –

Antwort

4

Die Antwort war ganz einfach:

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.

Das ist es.

UPD:

Inlining ist hier wichtig. Aus diesem Grund kann die außerhalb der Klassendefinition definierte Friend-Funktion keine statischen Member der Klasse direkt verwenden. Zum Beispiel Pritns der folgende Code kompilieren Zeitfehler:

#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

Ich bin froh, dass Sie die Antwort gefunden haben. :) –