Die {}
Syntax ist eine verspannt-init-Liste, und da es als ein Argument in einem Funktionsaufruf verwendet wird, ist es copy-Liste initialisiert ein entsprechender Parameter.
§ 8.5 [dcl.init]/p17:
(17,1) - Wenn der Initialisierer eine (nicht eingeklammerten) ist verspannt-init-Liste, das Objekt oder die Referenz-Liste -initialisiert (8.5.4).
§ 8.5.4 [dcl.init.list]/p1:
List-Initialisierung ist die Initialisierung eines Objekts oder eine Referenz von einer verspannt-init-Liste. Ein solcher Initialisierer ist , der als Initialisierungsliste bezeichnet wird, und die durch Kommas getrennten Initialisierungsklauseln der Liste werden die Elemente der Initialisierungsliste genannt. Eine Initialisierungsliste ist möglicherweise leer. Listeninitialisierung kann in Direktinitialisierung auftreten oder Kopierinitialisierung Kontexte; [...]
Für einen Klasse-Typ-Parameter, mit list-Initialisierung, Überladungsauflösung sieht in zwei Phasen für einen lebensfähigen Konstruktor up:
§ 13.3.1.7 [over.match.list]/p1:
Wenn Objekte von nicht-aggregierte Klassentyp T
Liste initialisiert (8.5.4) sind, wählt die Überladungsauflösung des Konstruktors in zwei Phasen:
- Anfänglich ar die Kandidatenfunktionen e die Initialisiererlisten-Konstruktoren (8.5.4) der Klasse T
und die Argumentliste besteht aus der Initialisiererliste als einzelnes Argument.
- Wenn kein ausführbarer Initialisierungslistenkonstruktor gefunden wird, wird die Überladungsauflösung erneut ausgeführt, wobei die Kandidatenfunktionen alle Konstruktoren der Klasse T
sind und die Argumentliste aus den Elementen der Initialisierungsliste besteht.
aber:
Wenn die Initialisiererliste keine Elemente hat und T
einen Standardkonstruktor hat, wird die erste Phase weggelassen.
Da std::deque<T>
definiert einen nicht-expliziten Standardkonstruktors wird ein für die Überladungsauflösung auf einen Satz von lebensfähigen Funktionen hinzugefügt. Initialisierung durch einen Konstruktor wird klassifiziert als benutzerdefinierten Umwandlungs (§ 13.3.3.1.5 [over.ics.list]/p4):
Andernfalls, wenn der Parameter eine nicht-aggregierte Klasse ist X
und Überladungsauflösung gemäß 13.3.1.7 wählt einen einzigen besten Konstruktor von X
aus, um die Initialisierung eines Objekts vom Typ X
aus der Argumentinitialisierungsliste auszuführen. Die implizite Konvertierungssequenz ist eine benutzerdefinierte Konvertierungssequenz mit der zweiten Standardkonvertierung Sequenz einer Identitätskonvertierung.
Weiter zu gehen, wird eine leere verspannt-init-Liste kann seinen entsprechenden Parameter (§ 8.5.4 [dcl.init.list]/p3), der für literal Typen steht für Null-Initialisierungswert initialisieren:
(3.7) - Andernfalls, wenn die Initialisierungsliste keine Elemente enthält, wird das Objekt initialisiert.
Dies, für wörtliche Typen wie bool
, erfordert keine Umwandlung und wird als Standardkonvertierung klassifiziert (13.3.3.1.5 [over.ics.list]/p7 §):
Andernfalls
, wenn der Parametertyp keine Klasse ist:
(7,2) - wenn die Initialisiererliste keine Elemente aufweist, die implizite Umwandlungsfolge ist die Identitätsumwandlung.
[Beispiel:
void f(int);
f({ });
// OK: identity conversion
- Ende Beispiel]
Überlastungs Auflösung Kontrollen in erster Linie, wenn es ein Argument vorhanden ist, für die eine Umwandlungsfolge auf einen entsprechenden Parameter ist besser als in einer anderen Überlast (§ 13.3.3 [over.match.best]/p1):
[...] diese Definitionen gegeben, eine tragfähige Funktion F1
definierte eine bessere Funktion als eine andere tragfähige Funktion F2
sein, wenn für alle Argumente i
, ICSi(F1)
keine schlechte Umwandlungsfolge als ICSi(F2)
ist, und dann:
(1.3) - für einige Argument j
ist ICSj(F1)
eine bessere Conversion-Sequenz als ICSj(F2)
, oder, wenn nicht, dass [...]
Conversion-Sequenzen gemäß § 13.3.3.2 rangieren [über .ics.rank]/P2:
Wenn die Grundformen von impliziten Konvertierungssequenzen zu vergleichen
(wie in 13.3.3.1 definiert)
(2,1) - eine Standardkonvertierungssequenz (13.3.3.1.1) ist ein besseres Umwandlungsfolge als eine benutzerdefinierte Konvertierungssequenz oder einer Ellipsen-Umwandlungsfolge, und [...]
als solche wird die erste Überlast mit bool
mit {}
initialisiert wird als bessere Übereinstimmung betrachtet.
'{}' ist eine * verspannt-init-Liste *; Es hat keinen Typ. 'std :: initializer_list' ist eine andere Sache. –
Ich weiß nicht, wie interessiert Sie daran sind, aber die erste wird ausgewählt, weil '{}' -> 'bool' die Identitätskonvertierung ist und' {} '->' std :: deque 'ist ein Benutzer- definierte Konvertierungssequenz 'arg3' spielt bei der Überladungsauflösung keine Rolle, und der Parameter' bool arg2 = false' wird wie 'bool arg2' behandelt, da es zwei Argumente gibt. –
chris