2014-05-23 15 views
27

Wenn eine Lambda-Funktion innerhalb einer Funktion F, die ein Freund der Klasse C ist, deklariert, hat die Lambda-Funktion Zugriff auf C private Mitglieder? Konkret, erlaubt der Standard dies?C++ Lambda-Freundschaft

+0

Haben Sie versucht, einen Code zu sehen, wie die Compiler reagieren? –

+13

@RSahu ja, aber das ist keine sehr gute Strategie um festzustellen, ob Code legal ist. – Anycorn

+9

@Anycorn, worüber du sprichst, alle C++ - Compiler sind zu 100% in Übereinstimmung mit C++ 11 Standards;) – CoryKramer

Antwort

16

C++ 11 § [expr.prim.lambda] 5.1.2/3:

Der Typ des lambda-Ausdruck (was auch die Art des Verschlusses Objekt ist) ist ein eindeutiger, unbenannter Nicht-Vereinigungsklassen-Typ - der Verschlusstyp genannt wird - dessen Eigenschaften nachfolgend beschrieben werden. Dieser Klassentyp ist kein Aggregat (8.5.1). Der Closure-Typ wird im kleinsten Blockbereich, Klassenbereich oder Namespacebereich deklariert, der den entsprechenden Lambda-Ausdruck enthält. ...

Da die Verschlusstyp innerhalb der Friend-Funktion deklariert wird, wird es den gleichen Zugang gemäß § haben [class.local] 9.8/1:

Eine Klasse kann innerhalb eines deklariert werden Funktionsdefinition; Eine solche Klasse wird lokale Klasse genannt. Der Name einer lokalen Klasse ist lokal für den umgebenden Gültigkeitsbereich. Die lokale Klasse befindet sich im Geltungsbereich des umschließenden Bereichs und hat denselben Zugriff auf Namen außerhalb der Funktion wie die umschließende Funktion. ...

+0

@hvd Ja, behoben. – Casey

12

Eine verschachtelte Klasse hat automatisch Zugriff auf alle Mitglieder, auf die ihr "Besitzer" Zugriff hat. Sie müssen nicht lambdas brauchen, das zu sehen:

class A { 
    friend struct B; 
    friend void g(); 
    static void f() { } 
}; 

struct B { 
    struct C { 
    static void f() { A::f(); } 
    }; 
    static void f() { C::f(); } 
}; 

void g() { 
    struct D { 
    static void f() { A::f(); } 
    }; 
    D::f(); 
} 

Trotz nicht explizit aufgeführt werden als Freunde, C::f und D::f den privaten A::f ohne Beanstandungen vom Compiler aufrufen können.

Lambdas werden mithilfe von vom Compiler generierten lokalen Klassen implementiert (dies ist nicht nur ein Implementierungsdetail, das ist es, was der Standard erfordert), daher gelten dieselben Regeln wie für andere lokale Klassen.

Die Regel, dass lokale Klassen die gleichen Elemente zugreifen können, wird in 9.8 im Standard buchstabiert:

Die lokale Klasse im Rahmen des umschließenden Umfang ist, und hat den gleichen Zugang zu den Namen außerhalb der Funktion wie die umschließende Funktion.