2014-12-20 13 views
6

den Code vor:Diskrepanz zwischen Klirren und g ++ mit konst Umgang Objekte

struct Foo 
{ 
    int x = 10; 
}; 

int main() 
{ 
    const Foo foo; 
} 

unter g kompiliert ++ http://coliru.stacked-crooked.com/a/99bd8006e10b47ef jedoch spuckt einen Fehler unter Klirren ++ http://coliru.stacked-crooked.com/a/93f94f7d9625b579:

error: default initialization of an object of const type 
     'const Foo' requires a user-provided default constructor 

Ich bin nicht sicher, wer genau hier. Warum brauchen wir einen Standard-Ctor, da wir eine Initialisierung in der Klasse durchführen?

+0

Hier ist eine gute Antwort. http://stackoverflow.com/questions/7411515/why-does-c-require-a-user-provided-default-constructor-to-default-construct-a – Thellimist

+2

Das ist [CWG Ausgabe 253] (http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#253). –

+0

@Furkan, beachten Sie, dass ich weiß, warum die Regel so ist, wie ich es verstehe, ich verstehe nicht, warum es in meinem Fall anwendbar ist, da mein Objekt zur Laufzeit perfekt definiert ist. – vsoftco

Antwort

7

Ein Objekt des Klassentyps darf nur dann default-initialisiert werden, wenn es einen vom Benutzer bereitgestellten Standardkonstruktor hat. Von [dcl.init]/7:

Wenn ein Programm fordert die Default-Initialisierung eines Objekts eines const qualifizierten Typ T, T ist ein Klasse-Typ mit einem vom Benutzer bereitgestellten Standard-Konstruktor sein.

Ihre Klasse Foo hat das nicht; Das Vorhandensein eines -Klammer-oder-equals-Initialisierer erstellt einen von Benutzer bereitgestellten Standardkonstruktor nicht. Eher hat Ihre Klasse einen implizit definierten Standardkonstruktor, dessen Aktion die Initialisierung enthält, wie von der geschweiften oder gleichwertigen Initialisierer angefordert. (Clang hat Recht.)

([dcl.fct.def.default], insbesondere Absatz 5, bezieht sich auf die Definitionen von "vom Benutzer bereitgestellt", "explizit voreingestellt", "implizit deklariert" und "definiert als gelöscht" .“der gesamte Abschnitt ist wissenswert)

By the way, es ist einfach Standard-Initialisierung in C++ 11 zu vermeiden.

const Foo foo {}; // hunky-dory 
+0

** + 1 ** für die "hunky dory". :) –

+0

Welchen Unterschied macht '{}' ?? – 0x499602D2

+0

@ 0x499602D2 es Wert-initialisiert, so ist der Compiler glücklich, dass Sie in einem 'const' alles initialisiert haben. Ich denke, das Problem in meinem Fall ist, wenn Sie eine zusätzliche 'y'-Variable haben, die Sie nicht in der Klasse initialisieren. Standard-C++ entschied, dass es nicht stören wird, zu überprüfen, ob alle Mitglieder in der Klasse initialisiert sind, so dass die alte Regel immer noch anwendbar ist. – vsoftco

3

clang scheint zu sein, direkt nach 8,5 [dcl.init ] Absatz 7 letzter Satz:

Wenn ein Programm die Standardinitialisierung eines Objekts eines const -qualifizierten Typs T aufruft, sollte T ein Klassentyp mit einem vom Benutzer bereitgestellten Standardkonstruktor sein.

Offensichtlich hat der Typ keinen vom Benutzer bereitgestellten Standardkonstruktor.

Verwandte Themen