Initialisierungslistenobjekte in C++
Ein Initialisierungslistenobjekt ist ein Objekt, dessen Typ eine Anwendung der Schablone »::std::initializer_list« ist. Solch ein Objekt kann, wie ein Vektor, mehrere andere Objekte enthalten kann, die alle denselben Typ haben. In Vergleich zu einem Vektor hat ein Initialisierungslistenobjekt aber nur wenig Elementfunktionen.
Die Initialisierungslistenschreibweise »{ 11, 8, 2 }« kann zur Initialisierung eines Initialisierungslistenobjektes herangezogen werden, sie kann aber nicht allgemein als Ausdruck verwendet werden, sondern nur zu einer Initialisierung. In solch einem Fall wird sie bei der Überladungsauflösung wie ein Ausdruck vom Typ »::std::initializer_list< T >« behandelt, wobei »T « für einen Typ steht, der aus dem Inhalt so abgeleitet
Der konstruierte Typ »::std::initializer_list< char >« steht beispielsweise für eine Initialisierungsliste von char-Werten.
Ein Initialisierungslistenobjekt hat sie kaum eigene Elementfunktionen, da es vor allem zur Initialisierung anderer Objekte gedacht sind. Eine der wenigen Elementfunktionen ist »size()«.
Bei Verwendung von Initialisierungslisten muß die Direktive »#include <initializer_list>« vorangestellt werden, allerdings kann dies entfallen, wenn man nachgelesen hat, daß schon eine andere verwendete Direktive den Köpfer »<initializer_list>« inkludiert.
main.cpp
#include <initializer_list>
#include <ostream>
#include <iostream>
#include <string>int main()
{ ::std::initializer_list< char > l { 'a', 'b', 'c' };
::std::basic_string< char > s { 'a', 'b', 'c' };
::std::cout << l.size() << '\n';
::std::cout << s.size() << '\n'; }transcript
3
3
»auto« in der Direkt-Listeninitialisierung
Für den Typspezifizierer »auto« gibt es eine Sonderregel für die Direkt-Listeninitialisierung: Diese verlangt eine Initialisierungsliste mit einem einzigen Eintrag und dieser gibt dann den Typ und Wert des zu initialisierenden Objektes vor.
main.cpp
#include <initializer_list>
#include <ostream>
#include <iostream>int main()
{ auto a { 57 };
::std::cout << sizeof a << '\n';
::std::cout << sizeof( int )<< '\n';
::std::cout << a << '\n'; }transcript
4
4
57
Eine Listeninitialisierung mit runden Klammern (»auto a ( { 57 } )«) ist hier nicht gestattet.
- Zitat C++ 2016-11 7.1.7.4.1p2.2
- If the initialization is direct-list-initialization, the initializer shall be a braced-init-list containing only a single assignment-expression
»auto« in der Kopierinitialisierung
Falls tatsächlich eine Initialisierungsliste mit »auto« initialisiert werden soll, muß Kopierinitialisierung mit einer Initialisierungsliste verwendet werden.
main.cpp
#include <initializer_list>
#include <ostream>
#include <iostream>int main()
{ auto a ={ 3, 5, 9, 16, 48 };
::std::cout << a.size() << '\n'; }transcript
5
Initialisierungen ohne »auto«
Falls man eine Initialisierungslistenschreibweise verwenden will, um ein Objekt eines bestimmten Typs zu initialisieren, das weder einen fundamentalen Typ hat noch ein Initialisierungslistenobjekt sein soll, kann man mit den uns bisher bekannten Techniken »auto« nicht verwenden und muß den zu verwendenden Typ, wie beispielsweise »::std::string« dann explizit angeben.
main.cpp
#include <initializer_list>
#include <ostream>
#include <iostream>
#include <string>int main()
{ ::std::string a ={ 'a', 'b' };
::std::cout << a << '\n'; }transcript
ab