2017-09-19 7 views
8

Welche Auswirkungen hat das Umbrechen einer Initialisierungsliste in Klammern? Ist es einfach ein anderes Formular für die Initialisierung der Liste oder funktioniert es nur in bestimmten Szenarien?Welche Auswirkungen hat das Umbrechen einer Initialisierungsliste in Klammern?

Betrachten wir zum Beispiel a:

struct A { 
    A(float a, float b) {} 
}; 

int main() 
{ 
    A b(1.0f, 0.0f); // Direct initalization, finds ctor for (float, float) 
    A c{1.0f, 0.0f}; // List initalization, finds a matching ctor 

    A a({1.0f, 0.0f}); // Is this list initalization... which is expanded? 
} 

Antwort

10

A a(something) sagt a von something konstruieren. Wenn wir also something durch {1.0f, 0.0f} ersetzen, müssen wir einen Konstruktor finden, in dem der Parmeter mit {1.0f, 0.0f} initialisiert werden kann. Die einzigen Konstruktoren, die wir haben, sind die Standard-Konstruktoren für Kopieren und Verschieben, die const A& bzw. A&& übernehmen.

So tun

A a({1.0f, 0.0f}); 

Wird tatsächlich eine temporäre A erstellen und verwenden Sie dann, dass die vorübergehende a zu initialisieren. In diesem Fall wird der Verschiebungskonstruktor verwendet, da das Objekt beweglich ist und Verschiebungskonstruktoren zum Kopieren von Konstruktoren beim Umgang mit Rvalues ​​bevorzugt werden.

+0

Diese verdammten impliziten Konstruktoren ... braucht Zeit, sich daran zu gewöhnen. Vielen Dank! – Raginator

+0

@Raginator Kein Problem. Ich habe gerade die Antwort aktualisiert, um auch die Bewegungssemantik einzuschließen, da in diesem Fall der Move-Konstruktor anstelle des Kopierkonstruktors verwendet wird, da es besser passt. – NathanOliver

+3

Obwohl technisch korrekt, wird kein Verschiebungs- oder Kopierkonstruktor aufgerufen, da sie weggelassen werden (sogar obligatorische Kopie Elision in C++ 17). Während in C++ 14 diese Konstruktoren noch zugänglich sein müssen, können sie sogar in C++ 17 gelöscht werden. – Jodocus

Verwandte Themen