Wenn Sie Ihre eigenen -Konstruktoren nicht definieren wird A b(a)
als ein Aggregat (dh plain-old-data em>) Speichertyp betrachtet.
Beim Umgang mit einem Aggregat berücksichtigt list-initialization keine implizit deklarierten Konstruktoren, sondern versucht stattdessen, die Mitglieder Ihres Objekts direkt zu initialisieren.
Im Falle von A b{a}
, wobei %code% ein Aggregat ist, versucht der Compiler das erste Element in %code% mit dem Wert von %code% zu initialisieren; Das wird natürlich fehlschlagen, da %code% keine Mitglieder enthält.
Was sagt der Standard?
%code%
1) Ein Aggregat ist ein Array oder eine Klasse (Abschnitt 9), das vom Benutzer nicht bereitgestellt wird
Konstruktoren (12.1) , keine Klammer-oder-Gleich-Initialisierung für nicht-statische
Datenmitglieder (9.2), keine privaten oder geschützten nicht-statischen Datenmitglieder
(Abschnitt 11), keine Basisklassen (Abschnitt 10) und keine virtuellen Funktionen
(10.3).
2) Wenn ein Aggregat von einer Initialisierungsliste initialisiert wird, wie z
In 8.5.4 sind die Elemente des Initialisierers als
Initialisierer für die Mitglieder des Aggregats , in steigendem Index
oder Mitglied bestellen. Jedes Mitglied wird von der Kopie initialisiert
entsprechende Initialisierungsklausel. Wenn die Initialisierungsklausel ein
Ausdruck und eine verengende Konvertierung (8.5.4) ist erforderlich, um zu konvertieren
der Ausdruck, das Programm ist schlecht geformt.
___ qstnhdr ___ C ++ 11 in gcc 4.8.1: list-initialization für den Kopierkonstruktor funktioniert nicht
___ tag123c ___ C ++ ist eine universelle Programmiersprache. Es wurde ursprünglich als Erweiterung von C entworfen und behält eine ähnliche Syntax, ist aber jetzt eine komplett andere Sprache. Verwenden Sie dieses Tag für Fragen zu Code, der mit einem C ++ - Compiler kompiliert werden soll.
___ tag123c11 ___ C ++ 11 ist eine 2011 verabschiedete Version des C ++ - Sprachstandards. Sie hat viele Änderungen und Ergänzungen der Kernsprache sowie der verbesserten und erweiterten C ++ - Standardbibliothek vorgenommen.
___ answer19116144 ___
GCC folgt dem Standard, aber das ist ein bekannter Defekt, siehe Kern Ausgabe 1467 und wird wahrscheinlich bald behoben werden.
___ tag123gcc ___ GCC ist die GNU Compiler-Sammlung. Es ist der De-facto-Standard-C-Compiler unter Linux und unterstützt auch viele andere Sprachen und Plattformen.
___ tag123uniforminitialization ___ Ein C ++ 11-Feature, mit dem geschweifte Klammern verwendet werden können, um einen beliebigen Typ von Variablen in einem beliebigen Kontext zu initialisieren
___ qstntxt ___
Ich ermutige mit diesem Problem:
Wenn ich
habe
%Vor%
gcc gibt:
moves.cc: In der Funktion 'int main ()':
moves.cc:15:7: Fehler: zu viele Initialisierer für 'A'
A b {a};
Aber wenn ich A b (a) anstelle von A b {a} verwende, wird alles korrekt kompiliert. Und wenn ich default constructor deklariere, kompiliert es auch. Warum funktioniert es so?
Die Klasse ist ein Aggregat, also führt die list-Initialisierung eine Aggregat-Initialisierung durch und berücksichtigt die implizit deklarierten Konstruktoren nicht.
Da keine Datenelemente vorhanden sind, kann nur eine leere Liste ein gültiger Aggregatinitialisierer sein.
Aber wenn ich %code% anstelle von %code% verwende, kompiliere alles korrekt.
Bei der direkten Initialisierung wird der implizite Konstruktor verwendet, anstatt die Aggregat-Initialisierung zu versuchen.
Und wenn ich default constructor deklariere, kompiliert es auch.
Durch die Deklaration eines Konstruktors ist die Klasse kein Aggregat mehr und kann nur mit einem Konstruktor initialisiert werden.