Dieser Entwurfsstandard zeigt die Synopse für initializer_list
. Es hat keinen privaten Konstruktor.
Aber zwei Standardbibliotheksimplementierungen, die ich mir angesehen habe, libstdc ++ und libc ++, bieten beide private Konstruktoren:
%Vor%Ich glaube, der Teil, wo dieser private Konstruktor "impliziert" ist, stammt aus §8.5.4 / 5:
Ein Objekt vom Typ
std::initializer_list<E>
wird aus einem erstellt Initialisierungsliste, als ob die Implementierung ein temporäres Array zugewiesen hat von N Elementen vom Typconst E
, wobei N die Anzahl der Elemente ist in der Initialisierungsliste. Jedes Element dieses Arrays ist copy-initialisiert mit dem entsprechenden Element des Initialisierers Liste, und dasstd::initializer_list<E>
-Objekt ist zu konstruiert beziehen sich auf dieses Array.
Meine Fragen sind also:
Ist die Zusammenfassung zu niedrig angegeben?
Benötigt die Bibliothek einen privaten Konstruktor? Was macht der Compiler nicht?
Ist die Zusammenfassung zu niedrig angegeben?
Nein, es dokumentiert die benutzerorientierten Bits der initializer_list
-Klassenvorlage, die Teile, die Sie tatsächlich in Ihrem Code verwenden dürfen. Laut der Übersicht enthält die Vorlage nur einen Standardkonstruktor, mit dem Sie ein leeres initializer_list
s erstellen können, was eindeutig nicht sehr nützlich ist. % Co_de% ist jedoch ein Typ, der davon abhängt, dass magic vom Compiler ausgeführt wird. Mit Magie beziehe ich mich auf § 8.5.4 / 5, die Sie zitiert haben. Dies ermöglicht die folgende Aussage legal und kompilieren.
Hier, wie in Abschnitt 8.5.4 / 5 erklärt, erstellt der Compiler ein Array, das die vier ganzen Zahlen enthält, und initialisiert dann die initializer_list<T>
-Instanz entweder mit einem Zeigerpaar (erstes Element und eines nach dem Endelement). oder ein Zeiger und eine Länge (was sowohl libstdc ++ als auch libc ++ zu tun scheinen).
Sobald die Instanz erstellt wurde, kann Ihr Code auf alle in der Übersicht aufgelisteten Mitgliedsfunktionen zugreifen.
Benötigt die Bibliothek einen privaten Konstruktor? Was macht der Compiler nicht?
Wie der Kommentar oberhalb der privaten Konstruktordefinition libstdc ++ andeutet, ist der Compiler in der Lage, Code zu erzeugen, der die normale Zugriffskontrolle umgeht, also nein, ich würde sagen, dass es nicht notwendig ist, diesen Konstruktor zu haben. Der Compiler könnte den Standardkonstruktor verwenden, um eine leere initializer_list<int>
-Instanz zu erstellen, und dann den privaten Datenmitgliedern entsprechende Werte zuweisen (diese sind ebenfalls nicht in der Synopsis aufgeführt, sind aber notwendig).
Aber warum sollte man sich mit dieser Ungeschicklichkeit herumschlagen, wenn ein privater Konstruktor eine saubere Schnittstelle bietet, die der Compiler aufrufen kann?
Die Frage läuft darauf hinaus, ob eine Implementierung etwas definieren kann, was über den Standard hinausgeht. Ja, das ist möglich.
In der Tat §17.6.5.5 (Entwurf Nr. 3797) heißt es:
Ein Aufruf einer Memberfunktionssignatur, die im C ++ - Standard beschrieben wird Bibliothek verhält sich so, als würde die Implementierung kein zusätzliches Mitglied deklarieren Funktionssignaturen.
Fußnote 189:
189) Ein gültiges C ++ - Programm ruft immer das erwartete Bibliotheksmitglied auf Funktion oder eine mit äquivalentem Verhalten. Eine Implementierung kann Definieren Sie außerdem zusätzliche Elementfunktionen, die andernfalls nicht vorhanden wären aufgerufen von einem gültigen C ++ - Programm.
Sie dürfen nicht anrufen, um diese zusätzlichen Mitgliedsfunktionen aufzurufen, auch wenn sie zugänglich sind.
std::initializer_list
Benötigt die Bibliothek einen privaten Konstruktor? Was macht der Compiler nicht?
Der Standard definiert, was Sie erwarten würden, wenn Sie eine std::initializer_list<T>
aus einer Initialisierungsliste erstellen. Die Art und Weise, wie es gemacht wird, ist implementation-defined und, wie oben erwähnt, kann es daher einen private
-Konstruktor aufrufen.
Tags und Links c++ c++11 language-lawyer c++-standard-library