Ich habe eine Kopier- / Verschiebeprüfklasse:
%Vor%Und ich habe festgestellt, dass running:
%Vor%Erzeugt die folgende Ausgabe:
%Vor% Warum wird die Initialisierung nicht einfach die Objekte verschieben? Ich weiß, dass std::vector
unerwünschte Kopien bei der Größenänderung erstellen kann , aber wie Sie sehen können, hat das Hinzufügen von noexcept
hier nicht geholfen (und außerdem glaube ich nicht, dass die Gründe für die Größenänderung zur Initialisierung führen).
Wenn ich stattdessen Folgendes tue:
%Vor%Ich bekomme keine Kopien.
Getestet mit GCC 5.4 und Clang 3.8.
Dies ist nicht std::vector
, sondern std::initializer_list
.
std::initializer_list
wird von einem const
Array von Elementen unterstützt. Es erlaubt nicht% const
Zugriff auf seine Daten.
Dies blockiert die Bewegung von seinen Daten.
Aber das ist C ++, also können wir das lösen:
%Vor%Jetzt bekommen wir:
%Vor%gibt Ihnen 1 zusätzliche Bewegung pro Element:
%Vor%Wir können diese Extra-Instanz mit einem sorgfältigen Reservierungs- und Einrückungs-Schritt eliminieren:
%Vor% Live-Beispiel von beiden - tausche einfach v2::
gegen v1::
, um den ersten zu sehen Aktion.
Ausgabe:
%Vor% es könnte ein bisschen mehr Vektor-Overhead hier sein, da es für den Compiler schwierig sein kann zu beweisen, dass emplace_back
keine Neuzuweisung verursacht (obwohl wir es beweisen können), so dass redundante Tests höchstwahrscheinlich kompiliert werden. (Meiner Meinung nach brauchen wir eine emplace_back_unsafe
, die UB ist, wenn die Kapazität nicht ausreicht).
Der Verlust der zusätzlichen Menge von A
s ist es wahrscheinlich wert.
Eine andere Wahl:
%Vor%welches wie
benutzt wird %Vor%Hier müssen Sie angeben, wie viele Elemente manuell eingegeben werden sollen. Es ist so effizient wie die Version 2 oben.
Tags und Links c++ c++11 vector move-semantics