Mögliche Duplikate:
Kann ich einen Vektor des Nur-Bewegungstyps listen-initialisieren?
Edit 1: Bitte erwägen Sie eine erneute offene Abstimmung: Meine Frage betont die In-Place-Konstruktion. Move Construction ist eine Alternative, aber nicht das, worum es in diesen Fragen geht. Danke für die Antworten!
Edit 2: Da ich diese Frage nicht beantworten kann (es wurde geschlossen) poste ich hier meinen eigenen Vorschlag. Das Folgende ist nicht so gut wie die Antworten, die ich akzeptiert habe, aber es kann für andere nützlich sein. Zumindest wird nur der Move-Konstruktor aufgerufen:
%Vor%Originaler Beitrag:
Wenn Sie über die Antwort auf diese Frage nachdenken: Initialisierung von Klassen innerhalb eines STL-Arrays von Vektoren Ich fand heraus, dass ich keinen Weg finden konnte, den Vektor aus einer Initialisierungsliste in-place zu konstruieren. Was vermisse ich?
Ich versuche jetzt, klarer zu sein, ich möchte diese (vollkommen korrekte) Initialisierung
%Vor%um einen ähnlichen Effekt zu erzielen:
%Vor%Im ersten Fall wird jedoch der copy -Konstruktor für A2 temporär beim Einfügen aufgerufen. Gibt es eine Möglichkeit, das zu vermeiden? Was sagt der Standard?
Ich habe es verzweifelt versucht
%Vor%aber das generiert einen zusätzlichen Aufruf an den Move-Konstruktor, was ich auch nicht erwartet habe. Ich wollte nur explizit darauf hinweisen, dass A2 ein temporäres ist, etwas, von dem ich dachte, dass es impliziert wurde.
Vollständiges Beispiel:
%Vor%Ausgabe:
%Vor% Die Initialisierung von std::vector
in Ihrem Snippet unterscheidet sich nicht von folgenden Schritten (wenn initializer_list
einen öffentlichen nicht expliziten Konstruktor oder std::vector
einen Array-Verweis akzeptiert hat.):
Es ist keine besondere Art, ein std::vector
zu konstruieren, das wirklich von der Implementierung profitieren könnte. Die Initialisierung von Listen ist eine allgemeine Möglichkeit, Typen "einheitlich" zu initialisieren. Daher kann std::vector
nicht anders als jeder andere benutzerdefinierte Typ dargestellt werden. Daher kommt es nicht in Frage, das Konstrukt im OP zu konstruieren.
Nun kann das Backing-Array (oder ein beliebiges konstantes Array) durch die Implementierung in einen Nur-Lese-Speicher gesetzt werden, weshalb
dies ist %Vor%ist nur
%Vor% Es ist also auch nicht möglich, aus std::initializer_list
herauszugehen.
Nun, gibt es eine Lösung? Ja, es gibt, und es ist eigentlich ein ziemlich leichtes!
Wir wollen eine freie Funktion haben, die einen Container und eine Anzahl von Tupeln annimmt, die der Anzahl der Elemente entsprechen, die Sie einfügen möchten. Die Tupel enthalten die Argumente für den Konstruktor des Containertyps. Einfach in der Theorie, einfach in der Praxis mit dem Indextrick (wo indices == seq
und build_indices == gen_seq
in der Code):
Live-Beispiel mit der Implementierung von seq
und gen_seq
.
Der obige Code ruft emplace_back_one
genau sizeof...(Tuples)
mal auf und übergibt jeweils ein Tupel in der Reihenfolge, in der sie an emplace_back
übergeben wurden. Dieser Code wird auch von links nach rechts sequenziert, was bedeutet, dass die Konstruktoren in derselben Reihenfolge aufgerufen werden, in der Sie die Tupel für sie übergeben haben. emplace_back_one
entpackt dann einfach das Tupel mit dem Index-Trick und übergibt die Argumente an c.emplace_back
.
Die Konstruktion eines Objekts über std::initializer_list
ist nicht anders als das Konstruieren eines Objekts von einem anderen Objekt . Das std::initializer_list
ist kein mystisches, phantasmatisches Konstrukt; es ist ein lebendes, atmendes C ++ - Objekt (wenn auch nur temporär). Als solches gehorcht es allen Regeln des regelmäßigen Lebens und atmet C ++ Objekte.
Die Aggregationsinitialisierung kann die Kopie / Verschiebungen effektiv verhindern, da es sich um eine Aggregat-Initialisierung handelt, ein rein kompilierbares Konstrukt. std::vector
ist viele Dinge; Ein Aggregat und ein Konstrukt zur Kompilierzeit gehören nicht dazu. Damit es sich von dem, was es gegeben hat, initialisiert, muss es tatsächlichen C ++ - Code ausführen, nicht Kompilierzeit. Es muss über jedes Element von initializer_list
iterieren und diese Werte entweder kopieren oder verschieben. Und letzteres ist nicht möglich, da std::initializer_list
nicht den Zugriff auf seine Member nicht const
gewährt.
Die Initialisiererlisteninitialisierung soll aussehen wie die Aggregat-Initialisierung aussehen, nicht so funktionieren. Das sind die Kosten für eine Laufzeit, dynamische Abstraktion wie std::vector
.
Tags und Links c++ c++11 initialization initializer-list
Fügen Sie %code% zu %code% und %code% zu %code%
hinzuIn Ihrem Code ist %code% zu label, in diesem Fall sollte das rechte Element das richtige Floating haben, um den genau verfügbaren Platz zu füllen. Andernfalls können Sie Floats entfernen und erreichen dies mit %code% und %code%
Und ja, sogar %code% funktioniert.
Um cross browser keinen Leerraum unterhalb von Textfeldern / Eingabefeldern zu haben, verwenden Sie:
%Vor%(getestet in deiner Geige, funktioniert)
Seltsamerweise ist hier die vertikale Ausrichtung der Schlüssel.
Nur eine Anmerkung, Sie brauchen den Rand nicht: 0, weil Sie bereits %code% haben. Für eine noch umfassendere Cross-Browser-Erfahrung für textarea könnten Sie auch %code% für IE und %code% für Browser mit Größenänderungsunterstützung verwenden.
Einige weitere Informationen darüber, warum es so funktioniert, wie es funktioniert: Mystery White Space unter Bild-Tag
Mein Textbereich hat eine zusätzliche Unterfüllung, aber ich kann die Quelle nicht finden. Ich habe den individuellen Code auf dieser Seite eingefügt:
Ich kann nicht die Quelle davon finden. Es hat Klasse "field":
%Vor%Jede Eingabe (Wortspiel) würde geschätzt werden:)