Warum kann Lambda in Static Initializer nicht auf private Klassenmitglieder in VC ++ 2013 zugreifen?
Betrachten Sie den folgenden Code:
#include <iostream>
class foo {
int var = 99;
public:
static int const i;
};
int const foo::i = [&] { return foo().var; }();
auto main() -> int {
std::cout << foo::i << std::endl;
return 0;
}
Berücksichtigung des Standards§ 9.4.2 / 2 Statische Datenelemente [class.static.data]:
Der Initialisierungsausdruck bei der Definition von astatic
Datenelement liegt im Bereich seiner Klasse.
und
§ 5.1.2 / 2 & 3 Lambda-Ausdrücke [expr.prim.lambda]:
2
Die Auswertung eines Lambda-Ausdrucks ergibt einen vorübergehenden Wert (12.2). Dieses temporäre Objekt wird als Abschlussobjekt bezeichnet. Ein Lambda-Ausdruck darf in einem nicht bewerteten Operanden nicht vorkommen (Satz 5). [Hinweis: Ein Abschlussobjekt verhält sich wie ein Funktionsobjekt (20.9) .- Endnote]
3
Der Typ des Lambda-Ausdrucks (der auch der Typ des Closure-Objekts ist) ist ein eindeutiger, unbenannter Typ einer Nicht-Union-Klasse - Closure-Typ genannt - dessen Eigenschaften im Folgenden beschrieben werden. Dieser Klassentyp ist kein Aggregat (8.5.1). Der Closure-Typ wird im kleinsten Blockbereich, Klassenbereich oder Namespace-Bereich deklariert, der den entsprechenden Lambda-Ausdruck enthält.
Wir kommen zu dem Schluss, dass das Lambda im Ausdruck:
int const foo::i = [&] { return foo().var; }();
kann zu Recht zugreifenprivate
Mitglieder vonclass foo
da es im Initialisierungsausdruck des deklariert und definiert iststatic
Mitgliedi
vonclass foo
, und als solches ist sein Geltungsbereich der Geltungsbereich vonclass foo
.
Der Code wird kompiliert und läuft einwandfreiGCC v4.8 undClang v3.4Es kann jedoch in VC ++ 2013 nicht kompiliert werden, was zu einem Compilerfehler führt:
Fehler C2248: 'foo :: var': Zugriff auf in Klasse 'foo' deklariertes privates Mitglied nicht möglich
Frage:
Handelt es sich bei dem oben aufgezeichneten Verhalten von VC ++ 2013 um einen Fehler oder handelt es sich um ein spezifisches Verhalten von VC ++ 2013, das durch Ändern bestimmter Compilereinstellungen geändert werden könnte?