2014-09-08 16 views
19

Der folgende C++ 11-Code erfolgreich auf meinem GCC kompiliert 4.8:C++ 11 private Standardkonstruktors

struct NonStack 
{ 
private: 
    NonStack() = default; 
public: 
    static NonStack* Create(){ 
    return new NonStack; 
    } 
}; 
NonStack a; 

int main() { } 

jedoch folgendes ein Übersetzungsfehler gibt:

struct NonStack 
{ 
private: 
    NonStack(){} 
}; 

NonStack a; 

int main() { } 

Warum wird die erste einer gelingt? Sollte der private Standardkonstruktor die Erstellung eines Objekts über NonStack a; nicht verbieten?

+2

Ihr Code wirklich [kompilieren] (http://coliru.stacked-crooked.com/a/55199811d96f1af7) auf gcc4.8, aber 4.9 lehnt es ab (wie es sollte). – Praetorian

+8

Diese Frage wäre besser, wenn da eine Frage wäre. –

+0

Sie können auch '= löschen;' den Konstruktor. Es sollte sich wie erwartet verhalten. – glampert

Antwort

17

Dies ist gcc bug 54812, der Compiler kann Zugriffsspezifizierer für explizit voreingestellte spezielle Memberfunktionen nicht berücksichtigen. Bug 56429, der als ein Duplikat des früheren markiert ist, hat einen Testfall, der fast identisch mit dem Beispiel in der Frage ist.

Die Lösungen sind auf gcc4.9 zu aktualisieren, wodurch das Problem behoben wird. Oder erstellen Sie einen leeren Body für den Konstruktor, anstatt ihn explizit zu defi- nieren, wie Sie es im zweiten Beispiel getan haben.

+3

Hinweis: Dieser Fehler verweist auf [Hauptsprachproblem 1507] (http: //www.open- std.org/jtc1/sc22/wg21/docs/cwg_defects.html # 1507). Es war kein Fehler in GCC. Der Standard verwendet wirklich, um zu sagen, dass, da der Konstruktor trivial war, der Konstruktor nicht aufgerufen wurde, und wenn der Konstruktor nicht aufgerufen wird, ist die Tatsache, dass es "privat" ist, kein Problem. – hvd

+0

@hvd Einverstanden, dass der private triviale Konstruktor unzugänglich aber wohlgeformt ist, war ein Fehler im Standard, aber der gcc-Fehlerbericht zeigt immer noch einen Fehler an, weil er diese Logik auf unzugängliche triviale Destruktoren anwendet. Die Antwort könnte jedoch besser formuliert sein, und ich werde es in Kürze aktualisieren. – Praetorian

+0

Ah richtig, das habe ich verpasst, der Standard hat dafür länger passende Formulierungen. Interessanterweise scheint der Standard immer noch kein Verbot zu enthalten, einen Zeiger auf einen unvollständigen Klassentyp zu löschen, der einen unzugänglichen trivialen Destruktor hätte, es ist nur undefiniertes Verhalten, wenn der Destruktor tatsächlich nicht-trivial ist. – hvd