Ich lese Willst du Speed? Pass by Value. von Dave Abrahams über copy elision und RVO. Und ich frage mich, warum brauchen wir die Kopie elision?
Mir wurde zu oft gesagt, dass Sie Funktionsargumente durch const-Verweis übergeben sollten, um das Kopieren zu vermeiden (fast jedes C ++ - Buch, das ich gelesen habe, erzählte mir davon).
Angenommen wir haben zwei Funktionen:
%Vor%Wenn das tatsächliche Argument ein rvalue ist, wird das Kopieren in beiden Funktionen vermieden. Wenn das tatsächliche Argument jedoch ein lvalue ist, wird das Kopieren nur in f1 vermieden, nicht in f2. Warum brauchen wir diese Funktion?
Übergeben Sie den Wert, wenn Sie trotzdem eine Kopie benötigen. Ob Sie die Signatur von f1 oder von f2 wählen, hängt vom Inhalt der Funktion ab. Zum Beispiel würden Sie in diesem Fall eine const-Referenz verwenden:
%Vor%Aber Sie würden in diesem Fall nach Wert gehen:
%Vor%weil die Alternative wäre:
%Vor% RVO trifft nicht auf Ihr Beispiel zu, da der Rückgabewert int
ist.
Tally: 1-2 Kopien in C ++ 03, genau 1 in C ++ 11 plus (wenn Elision deaktiviert ist) eine Bewegung, die zu einer Kopie für eine andere Klasse als std::string
degenerieren kann.
Tally: 0-2 Kopien in C ++ 03 oder 0-1 in C ++ 11.
Wie andere bereits gesagt haben, übergeben Sie den Wert, wenn Sie das Objekt als reinen Wert ohne Referenzsemantik manipulieren möchten.
const &
ist eine vertraute Sprache, aber in Bezug auf die Sprachsemantik ist es eine Art Klotz. Sie verwenden es, wenn Sie überhaupt keine Referenz möchten; Das &
dient nur dazu, das const
in der Parameterdefinition sinnvoll zu machen. Wenn Sie den Parameter ändern möchten (aber nur lokal), dann gilt const
nicht wirklich, und auch der &
fällt aus.
f2
signalisiert durch seine Unterschrift, egal was du mir übergibst, ich werde mich mit meiner eigenen Kopie deines Gegenstandes befassen. Nützlich, wenn f2
das Objekt auf eine nicht umkehrbare Art und Weise ändern wird (z. B. um seine Ressourcen durch Verschieben zu stehlen) oder in einigen Parallelitätsszenarien. Zugegebenermaßen fügt C ++ 11 dem (bereits verwirrenden) C ++ - Typ-System eine neue Ebene der Verwirrung hinzu, aber sobald man darüber nachdenkt, macht es viel Sinn ...