Liefert einen privaten Konstruktor für initializer_list konform?

8

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 Typ const 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 das std::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?

user4700874 22.03.2015, 21:24
quelle

2 Antworten

2
  

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.

%Vor%

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?

    
Praetorian 22.03.2015 22:08
quelle
1

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.

Bezüglich 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.

    
edmz 22.03.2015 22:40
quelle