C::f et C::g garde toutes les deux une copie du pointeur, mais f prend par référence et g par valeur. C::h prend possession du pointeur passé par référence de rvalue.
c.f(ptr_A) : le pointeur passé par référence puis copié dans la fonction -> 1 copie.
c.f(ptr_B) : le pointeur est converti, puis le temporaire est passé par référence, copié et détruit -> 2 copies, 1 destruction.
c.g(ptr_A) : le paramètre est crée par le constructeur de copie puis est déplacé par la fonction -> 1 copie, 1 déplacement, 1 destruction d'un pointeur nul (moins cher).
c.g(ptr_B) : pareil que le précédent sauf que le constructeur de copie est remplacé par la conversion.
c.h(std::move(ptr_A)) : passage par référence, puis affectation -> 1 déplacement.
c.h(std::move(ptr_B)) : conversion, passage par référence, puis affectation -> 2 déplacement, 1 destruction d'un pointeur nul.
J'espère que c'est plus clair. Le passage par référence nécessite une copie supplémentaire pour la conversion, alors que le passage par valeur permet de limiter à une seule copie dans tous les cas.
[^] # Re: Godbolt
Posté par Clément V . En réponse au journal Le quiz c++ de l'été. Évalué à 2.
Pour garder un exemple dans le style du journal, mais où on sait ce que font les fonctions : https://gcc.godbolt.org/z/2llMlg
C::fetC::ggarde toutes les deux une copie du pointeur, mais f prend par référence et g par valeur.C::hprend possession du pointeur passé par référence de rvalue.c.f(ptr_A): le pointeur passé par référence puis copié dans la fonction -> 1 copie.c.f(ptr_B): le pointeur est converti, puis le temporaire est passé par référence, copié et détruit -> 2 copies, 1 destruction.c.g(ptr_A): le paramètre est crée par le constructeur de copie puis est déplacé par la fonction -> 1 copie, 1 déplacement, 1 destruction d'un pointeur nul (moins cher).c.g(ptr_B): pareil que le précédent sauf que le constructeur de copie est remplacé par la conversion.c.h(std::move(ptr_A)): passage par référence, puis affectation -> 1 déplacement.c.h(std::move(ptr_B)): conversion, passage par référence, puis affectation -> 2 déplacement, 1 destruction d'un pointeur nul.J'espère que c'est plus clair. Le passage par référence nécessite une copie supplémentaire pour la conversion, alors que le passage par valeur permet de limiter à une seule copie dans tous les cas.