2017-09-29 1 views
6

Ich habe die KlasseStandardargument erlaubt Konstruktor private Methode zu nennen

class A 
{ 
public: 
    class Key 
    { 
     Key() {} 
     Key(Key const &) {} 
    }; 

    A(Key key, int a = 5) {} 
}; 

Der Konstruktor für Key privat ist, so sollte niemand in der Lage sein A ein Objekt zu konstruieren. Doch mit dem folgenden Code:

int main() { 
    A a(A::Key()); // this compiles !!! 
    A a2(A::Key(), 5); // this doesn't 
    // somehow defaulting the argument causes the private constructor 
    // to be OK - no idea why 
    return 0; 
} 

sich für int a in meinem Konstruktor Verwendung des Standardargument zu machen, kompiliert der Compiler glücklich meine Nutzung von A::Key() trotz der Tatsache, dass es privat ist. Wenn ich explizit einen Wert für a gebe, erkennt der Compiler jedoch korrekt, dass ich versuche, einen privaten Konstruktor zu verwenden, und Fehler aus. Warum ist das? Gibt es eine Möglichkeit, den Compiler auch für das erste Beispiel zu einem Fehler zu zwingen?

Siehe here für Live-Beispiel.

Antwort

7

Dies ist wegen der ärgerlichsten Parse.

A a(A::Key()); 

Schaff keine A namens a und baut mit einer temporären A::Key. Es erstellt eine Funktion a, die eine A zurückgibt und einen unbenannten Zeiger zu Funktion nimmt, die zurückgibt.

Wenn Sie ein Paar von Klammern, um es hinzuzufügen erhalten Sie einen Compiler-Fehler

A a((A::Key())); 

Dass Sie einen privaten Konstruktor aufzurufen versuchen. Alternativ können Sie auch uniformierte Initialisierung verwenden, welche es auch Mehrdeutigkeiten und einen Compiler-Fehler

A a(A::Key{}); 
+1

verursachen Ich wusste, dass ich das irgendwo gesehen hatte, bevor ... eines dieser Dinge, die ich in einmal laufen alle 5 Jahre und flummoxed bin von da Ich habe es nicht mehr so ​​lange gesehen ... Danke für die Hilfe. –

+1

@R_Kapp Kein Problem, froh zu helfen. – NathanOliver

Verwandte Themen