Ich habe erwartet, dass std::make_move_iterator
immer Inhalte verschieben wird, aber es scheint nicht.
Es sieht so aus, als ob Elemente in vector<string>
verschoben werden, aber nicht in vector<int>
.
Siehe das folgende Code-Snippet:
%Vor%Das Ergebnis ist:
%Vor% Ich bin bei Ubuntu 14.04, gcc 4.8.2
und der Code ist mit -std=c++11
Können Sie erklären, warum std::make_move_iterator
ein anderes Verhalten in vector<int>
und vector<string>
hat? (Oder ist es ein Fehler?)
Das Verhalten wird erwartet. Eine Bewegung von beiden Vektoren belässt die ursprüngliche v1
mit 5 verschobenen Elementen in ihrer zweiten Hälfte.
Der Unterschied besteht darin, dass beim Verschieben der Strings leere Strings zurückbleiben. Dies liegt daran, dass es eine sehr effiziente Möglichkeit ist, Zeichenketten zu verschieben und die verschobene Zeichenkette in einem selbstkonsistenten Zustand zu belassen (Technisch könnten sie den Wert "Hello, World, nice move!"
behalten, aber das würde zusätzliche Kosten verursachen). Die Quintessenz ist, dass Sie die von Strings verschobenen Zeichen nicht in Ihrer Ausgabe sehen.
Im Fall der Vektoren int
gibt es keine Möglichkeit, eine int
zu verschieben, die effizienter ist als das Kopieren, also werden sie einfach überkopiert.
Wenn Sie die Größe der Vektoren überprüfen, sehen Sie, dass die v1
in beiden Fällen die Größe 10 haben.
Hier ist ein vereinfachtes Beispiel um zu verdeutlichen, dass die aus Strings verschobenen Zeichen leer bleiben:
%Vor%Ausgabe:
%Vor%Wenn wir von move sprechen, sprechen wir nicht davon, das Objekt selbst zu bewegen (es bleibt intakt). Was bewegt wird, sind seine internen Daten. Dies kann den Wert des Objekts, dessen interne Daten verschoben werden, beeinflussen oder nicht.
Aus diesem Grund verliert Ihr int
-Array nicht seine ursprüngliche int
s. Was Ihr Beispiel betrifft, hat es immer noch das ursprüngliche std::strings
, genau wie das int
Beispiel, aber die internen Werte haben sich in leere Strings geändert.
Es ist wichtig, daran zu denken, dass intern ein std::string
(im Wesentlichen) einen Zeiger auf ein Zeichen-Array enthält. Wenn Sie kopieren ein std::string
kopieren Sie jedes Element des Zeichenarrays. Ein move vermeidet jedoch das Kopieren, indem stattdessen der interne Zeiger kopiert wird.
Aber wenn die Operation move dort angehalten würde, würde sowohl std::string
s auf das gleiche Zeichenarray zeigen als auch die Zeichendaten ändern, auf die entweder std::string
zeigt, würde auch die anderen verändern. Wenn Sie also eine Zeichenfolge verschieben, reicht es nicht aus, nur den internen Zeiger zu kopieren , sondern Sie müssen den internen Zeiger des std::string
vom Punkt auf einen neuen setzen leeres Zeichen-Array, so dass es die Zeichenfolge nicht mehr beeinflussen kann, in die die Daten verschoben wurden.
Beim Verschieben von int
ist nach dem Kopieren der Daten keine weitere Aktion erforderlich. Es gibt keine Zeiger, so dass nach der Kopie beide Ints unabhängige Daten enthalten.
Tags und Links string c++ c++11 vector move-semantics