Das folgende Zitat stammt von Effective Modern C ++ (Seite 55):
"Angenommen, Sie verwenden einen leeren Satz Klammern, um ein Objekt zu konstruieren, das den Standardkonstruktor unterstützt, und unterstützt auch die std :: initializer_list-Konstruktion. Was bedeuten Ihre leeren Klammern? usw. Die Regel ist, dass Sie die Standardkonstruktion erhalten."
Ich habe das mit std :: array versucht:
%Vor%und erhielt die Warnung von g ++ (Version 4.8.2):
Warnung: fehlender Initialisierer für Member 'std :: array & lt; int, 10ul & gt; :: _ M_elems'
Dies ist die Warnung, die man erhält, wenn man versucht, ein std::array
aus einem leeren std::initializer_list
zu konstruieren (siehe Warum kann ich ein reguläres Array von {} initialisieren, aber nicht ein std :: -Array , um diese Warnung zu erörtern?).
Warum wird die obige Codezeile nicht als Aufruf des Standardkonstruktors interpretiert?
Das liegt daran, dass std :: array ein Aggregat ist und daher aggregation initialization wird durchgeführt, dies wird in entwurf C ++ 11 Standard Abschnitt 8.5.4
[dcl.init.list] was sagt:
Die Listeninitialisierung eines Objekts oder einer Referenz vom Typ T ist wie folgt definiert:
Wenn die Initialisierungsliste keine Elemente enthält und T ein Klassentyp mit einem Standardkonstruktor ist, lautet das Objekt Wert initialisiert.
Andernfalls, wenn T ein Aggregat ist, wird eine Aggregatinitialisierung durchgeführt (8.5.1).
%Vor%
und wir können sehen, ob es kein Aggregat ist, dann geht die Liste weiter und sagt:
- Andernfalls, wenn T eine Spezialisierung von std :: initializer_list ist, ist ein initializer_list -Objekt wie unten beschrieben aufgebaut und verwendet, um das Objekt gemäß den Regeln für die Initialisierung zu initialisieren eines Objekts aus einer Klasse des gleichen Typs (8.5).
- Andernfalls, wenn T ein Klassentyp ist, werden Konstruktoren berücksichtigt. Die anwendbaren Konstruktoren werden aufgelistet und der beste wird durch Überladungsauflösung gewählt (13.3, 13.3.1.7). Wenn eine verkleinerte Konvertierung (siehe unten) ist erforderlich, um eines der Argumente zu konvertieren, das Programm ist schlecht gebildet.
Wir können bestätigen, dass std::array
ein Aggregat aus dem Abschnitt 23.3.2.1
[array.overview] ist:
Ein Array ist ein Aggregat (8.5.1), das mit dem initialisiert werden kann Syntax
%Vor%wobei die Initialisiererliste eine durch Kommas getrennte Liste von bis zu N Elementen ist deren Typen in T konvertierbar sind.
section 8.5.1
referenziert ist 8.5.1
Aggregates [dcl.init.aggr] und sagt:
Wenn ein Aggregat wie angegeben durch eine Initialisierungsliste initialisiert wird In 8.5.4 werden die Elemente der Initialisierungsliste als Initialisierer für die Mitglieder des Aggregats, in steigendem Index oder Mitgliederbestellung [...]
und wir kommen mit dem Vollkreis zurück zum Abschnitt 8.5.4
, wo wir angefangen haben.
Tags und Links c++ c++11 aggregate-initialization