Einführung
Für einen technischen Überblick - springen Sie zu dieser Antwort .
In häufigen Fällen, in denen eine Kopierentfernung auftritt, fahren Sie mit dieser Antwort fort .
Copy Elision ist eine Optimierung, die von den meisten Compilern implementiert wird, um in bestimmten Situationen zusätzliche (möglicherweise teure) Kopien zu vermeiden. Dies macht eine Rückgabe nach Wert oder Wertübergabe in der Praxis möglich (Einschränkungen gelten).
Dies ist die einzige Form der Optimierung, bei der (ha!) Die Als-ob-Regel außer Kraft gesetzt wird. Die Kopierelision kann angewendet werden, auch wenn das Kopieren / Verschieben des Objekts Nebenwirkungen hat .
Das folgende Beispiel stammt aus Wikipedia :
struct C {
C() {}
C(const C&) { std::cout << "A copy was made.\n"; }
};
C f() {
return C();
}
int main() {
std::cout << "Hello World!\n";
C obj = f();
}
Abhängig vom Compiler und den Einstellungen sind alle folgenden Ausgaben gültig :
Hallo Welt!
Eine Kopie wurde gemacht.
Eine Kopie wurde gemacht.
Hallo Welt!
Eine Kopie wurde gemacht.
Hallo Welt!
Dies bedeutet auch, dass weniger Objekte erstellt werden können, sodass Sie sich auch nicht darauf verlassen können, dass eine bestimmte Anzahl von Destruktoren aufgerufen wird. Sie sollten keine kritische Logik in Kopier- / Verschiebungskonstruktoren oder Destruktoren haben, da Sie sich nicht darauf verlassen können, dass sie aufgerufen werden.
Wenn ein Aufruf eines Kopier- oder Verschiebungskonstruktors aufgehoben wird, muss dieser Konstruktor noch vorhanden und zugänglich sein. Dies stellt sicher, dass die Kopierelision das Kopieren von Objekten nicht zulässt, die normalerweise nicht kopierbar sind, z. B. weil sie einen privaten oder gelöschten Kopier- / Verschiebungskonstruktor haben.
C ++ 17 : Ab C ++ 17 ist Copy Elision garantiert, wenn ein Objekt direkt zurückgegeben wird:
struct C {
C() {}
C(const C&) { std::cout << "A copy was made.\n"; }
};
C f() {
return C(); //Definitely performs copy elision
}
C g() {
C c;
return c; //Maybe performs copy elision
}
int main() {
std::cout << "Hello World!\n";
C obj = f(); //Copy constructor isn't called
}