Ich möchte einen großen Container aus einem Rückgabewert mithilfe des Konstruktors dieser Klasse in eine andere Klasse verschieben. Wie formuliere ich den Parameter, um sicherzustellen, dass er nicht kopiert wird?
%Vor%Wird obige Formulierung das entsprechende Verhalten auslösen, oder muss ich die Parameter des Konstruktors als rvalue-references angeben, so wie es die Container für ihre eigene move-semantics tun?
%Vor%oder
%Vor%...?
Wenn Sie das Kopieren von und unterstützen möchten, ist der einfachste Weg um nach Wert zu übergeben :
%Vor% Nun können Sie Bar
aus einem lvalue und einem rvalue konstruieren:
Wenn Sie nur rValues unterstützen möchten, verwenden Sie eine explizite rvalue-Referenz:
%Vor% Das std::move
ist immer notwendig, da (m)
immer ein lvalue ist.
Erzwinge die Übergabe von rvalue in den Konstruktor und stelle sicher, dass die Map wie folgt verschoben wird:
%Vor% Beginnen wir mit dem ersten Beispiel von Bar(umap m) : bm(m) {}
. Dies führt mindestens 1 Kopie, möglicherweise 2.
bm(m)
wird immer kopiert. m
ist hier lvalue , obwohl es an einen rvalue gebunden ist. Um es in Bewegung zu versetzen, müssen Sie es in std::move
umbrechen, um es in einen rvalue umzuwandeln. Wir erhalten bm(std::move(m))
.
Bar(umap m)
könnte kopieren. Der Wert wird verschoben, wenn es ein rvalue ist, wird aber kopiert, wenn es ein lvalue ist. Da wir alle Kopien verhindern wollen, müssen wir nur rvalue binden lassen. Wir erhalten Bar(umap && m)
.
Zusätzlich zu den obigen Antworten:
Was ich in Ihrem Beispiel sehe, ist ein klassischer Fall für die Optimierung "Kopieren Elision".
Was sind Kopieroptimierung und Rückgabewertoptimierung?
Ein tatsächlicher Compiler benötigt keine Unterstützung von Ihnen, um die Dinge zu optimieren, und es gibt keinen Grund, sich mit rvalue-Referenzen in diesem speziellen Fall der Rückgabewertoptimierung zu beschäftigen.
Tags und Links c++ c++11 parameters move-semantics