Rvalue-Referenzen ohne std :: move [duplicate]

8

Ich habe folgende Klasse

%Vor%

was ich im folgenden Code verwende

%Vor%

Das resultierende Verhalten ist für mich nachvollziehbar. Im ersten Aufruf wird ein Widget erstellt, dann wird der Move-Konstruktor aufgerufen und der Destruktor wird für das temporäre Widget aufgerufen.

Der zweite Aufruf macht dasselbe, erwarte, dass der move-Zuweisungsoperator statt des move-Konstruktors aufgerufen wird. Wenn Sie die main-Methode verlassen, wird der Destruktor in c aufgerufen.

Jetzt kommt der interessante Teil:

%Vor%

Wenn ich den Aufruf von std::move weglasse, hört der erste Fall auf zu arbeiten und führt nur zu einem Konstruktoraufruf. Während der zweite Fall noch funktioniert wie zuvor.

Was fehlt mir hier? Warum behandeln diese beiden Funktionsaufrufe ihre Parameter anders? Ich habe es auf gcc und clang versucht.

    
mike 05.05.2015, 16:01
quelle

1 Antwort

12

widget() ist ein reiner rvalue (prvalue), also in der Zeile

%Vor%

es wird verschoben. Der Compiler führt jedoch nur kopieren / verschieben elision aus. Kompilieren Sie mit -fno-elide-constructors und Sie werden die Aufrufe der Move-Konstruktoren in ihrer ganzen Pracht sehen.

Wenn Sie explizit std::move verwenden, um einen Pr-Wert zu verschieben, erlauben Sie dem Compiler nicht, die Elision auszuführen; Deshalb sehen Sie den Bewegungskonstruktor im ersten Ausschnitt in Aktion. Deshalb ist es fast immer eine schlechte Idee, dem Compiler zu "helfen", indem Sie als Rückgabe eine std::move verwenden (es sei denn, Sie möchten wirklich eine rvalue-Referenz zurückgeben).

    
vsoftco 05.05.2015, 16:07
quelle