La norme de référence
Pour moins de vue technique et introduction - passer à cette réponse.
Pour les cas fréquents où la copie élision se produit - passer à cette réponse.
Copie élision est défini dans la norme:
12.8 la Copie et le déplacement des objets de la classe [classe.copier]
comme
31) Lorsque certains critères sont respectés, une mise en œuvre est permis d'omettre de le copier/déplacer construction d'une classe
objet, même si le copier/déplacer constructeur et/ou le destructeur de l'objet ont des effets secondaires. Dans de tels cas,
la mise en œuvre traite de la source et de la cible de l'omis de copier/déplacer des fonctionnement que simplement deux
manières de se référer au même objet, et la destruction de cet objet se produit au plus tard à la fois
lorsque les deux objets ont été détruits sans l'optimisation.123 Cette élision de copier/déplacer
opérations, appelées copie élision, est autorisé dans les circonstances suivantes (qui peuvent être combinées pour
éliminer plusieurs copies):
- dans une instruction return dans une fonction avec une classe de type de retour, lorsque l'expression est le nom d'un
non-volatile automatique d'objets (autre qu'une fonction ou catch-clause de paramètre) avec le même cvunqualified
type que le type de retour de fonction, le copier/déplacer opération peut être omis, par la construction de
l'automatique des objets directement dans la fonction de valeur de retour
- dans un jet d'expression, lorsque l'opérande est le nom d'un non-volatile automatique d'objets (autres que les
fonction ou catch-clause de paramètre) dont la portée ne s'étend pas au-delà de la fin de l'intime
en joignant essayez-bloc (si il y en a un), le copier/déplacer le fonctionnement de l'opérande à l'exception
objet (15.1) peut être omis par la construction automatique de l'objet directement dans l'objet de l'exception
- lorsqu'un temporaire de la classe de l'objet qui n'a pas été lié à une référence (12.2) serait copié/déplacé
pour un objet de classe avec le même cv-non qualifiés de type, le copier/déplacer opération peut être omis par
la construction de l'objet temporaire directement dans la cible de l'omis de copier/déplacer
- lorsque l'exception-la déclaration d'un gestionnaire d'exception (article 15) déclare un objet de même type
(sauf pour le cv-qualification) que l'objet de l'exception (15.1), le copier/déplacer opération peut être omis
par le traitement de l'exception-déclaration comme un alias pour l'objet de l'exception si le sens du programme
sera inchangé, sauf pour l'exécution de constructeurs et destructeurs pour l'objet déclaré par
l'exception-déclaration.
123) Parce qu'un objet est détruit au lieu de deux, et un copier/déplacer constructeur n'est pas exécuté, il est toujours une
objet détruit pour chacun construit.
L'exemple donné est:
class Thing {
public:
Thing();
~Thing();
Thing(const Thing&);
};
Thing f() {
Thing t;
return t;
}
Thing t2 = f();
et d'expliquer:
Ici, les critères d'élision peuvent être combinés pour éliminer les deux appels au constructeur de copie de la classe Thing
:
la copie du ou des locaux automatique des objets t
dans l'objet temporaire pour la valeur de retour de la fonction f()
et la copie de l'objet temporaire d'objet t2
. Effectivement, la construction de l'objet local t
peut être considéré comme directement de l'initialisation de l'objet global t2
, et que l'objet de la destruction se fera au programme
à la sortie. L'ajout d'un constructeur de déplacement de Chose a le même effet, mais c'est le mouvement de construction de l'
objet temporaire pour t2
qui est élidée.