In C++ 11, so scheint es, wie es ein std::map<std::string, int>
wie folgt zu initialisieren legal ist:Welche Sprachregeln erlauben C++ 11, daraus abzuleiten, dass es sich um eine initialiser_list von Paaren handelt?
std::map<std::string, int> myMap = {
{ "One", 1 },
{ "Two", 2 },
{ "Three", 3 }
};
Intuitiv dies sinnvoll ist - die in geschweiften Klammern stehenden Initialisierer eine Liste von Paaren von Strings ist, und std::map<std::string, int>::value_type
ist std::pair<std::string, int>
(möglicherweise mit einigen const
Qualifikationen.
Allerdings bin ich mir nicht sicher, ich verstehe, wie die Typisierung hier funktioniert. Wenn wir die Variablendeklaration hier eliminieren und nur die geschweifte Initialisierer haben, würde der Compiler nicht wissen, dass es schaute auf eine std::initializer_list<std::pair<std::string, int>>
, weil es nicht wissen würde, dass die verspannten Paare re präsentiert std::pair
s. Daher scheint es, als ob der Compiler den Vorgang des Zuweisens eines Typen an den geschweiften Initialisierer irgendwie verzögert, bis es genügend Typeninformation von dem std::map
-Konstruktor hat, um zu erkennen, dass die geschachtelten geschweiften Klammern für Paare sind. Ich erinnere mich nicht, dass so etwas in C++ 03 passiert ist; Nach meinem besten Wissen hing der Typus eines Ausdrucks niemals von seinem Kontext ab.
Welche Sprachregeln erlauben die korrekte Kompilierung dieses Codes und die Festlegung des für die Initialisierungsliste zu verwendenden Typs durch den Compiler? Ich hoffe auf Antworten mit spezifischen Verweisen auf die C++ 11-Spezifikation, da es wirklich interessant ist, dass das funktioniert!
Danke!
In Klammern eingeschlossene Listen in C++ 03 waren bereits sehr spezifisch für den Initialisierungskontext. Es gibt hier keinen signifikanten Unterschied zu einem verschachtelten C++ 03-Aggregat (vielleicht 'std :: pair myArray []'), das mit geschweiften Klammern initialisiert wurde, außer dass der Typ nicht direkt benannt ist die verfügbaren Konstruktoren. –
BTW, implizite Konvertierungsoperatoren (Member 'operator T()') sind die andere Stelle, an der der Kontext den Typ eines Ausdrucks bestimmt (und für die Überladungsauflösung verwendet wird). –
'braced-init-list' ist kein Ausdruck und hat keinen Typ. Es gibt keinen Abzug, nur eine Überladungsauflösung unter den Initialisierungslisten-Konstruktoren (von denen es nur einen gibt) – Cubbi