Je voudrais faire quelque chose comme ça ma question est la suivante: l'ordre de l'argument de la fonction est indéterminé, il est donc prudent de passer une valeur qui sera déplacée d'une argument, et le résultat de l'appelant une autre fonction avec la même instance forte> forte>, passée comme référence-à-const, comme l'autre argument? P> Je pense que la question se résume à la fois quand, précisément, l'opération de déplacement réelle est effectuée, un point sur lequel je ne suis pas tout à fait clair (surtout quand il s'agit d'une optimisation allumée). P> P>
3 Réponses :
Le "déménagement" réel ne se produirait pas tant que le constructeur de déplacement de Puisque vous passez le std :: unique_ptr
std :: mouvement () code> est lancer le
const FoopTr & code> RValue dans un
FOOPTR && code> RValue Référence). Cela ne se produirait pas tant que les deux arguments
Baz CODE> Constructeur que vous déléguez sont invoqués. Pour que cela se produise, tous les arguments à ce constructeur doivent être évalués en premier. Par conséquent, toute utilisation de l'objet
FOO code> dans l'évaluation de ces arguments se produira avant le "mouvement" réel de l'instance
unique_ptr code>. P>
FOOPTR code> (AKA
std :: unique_ptr
std :: unique_ptr code> est mobile- Seulement, cela déclenchera une construction de déménagement lors de l'évaluation de la première dispute au constructeur à deux arguments. L'ordre d'évaluation des arguments étant indéterminé, que le déplacement peut ne pas se produire avant l'évaluation du deuxième argument. Par conséquent, le comportement de votre Exemple
Je pense que cela est incorrect car avant que le constructeur soit appelé, vous devez construire les arguments transmis par valeur. Construire FOOPTR FOO code> pour le second constructeur "Invalider"
FOO code>.
@Romanl: Oui, je pense que vous avez raison (voir le commentaire de l'autre réponse de Galop1n aussi).
Preuve, inversement Les deux arguments changent le résultat: Coliru.stacked-crooked.com/a/37f85e8A5397Eec2 < / a> (parce que Clang évaluait le plus souvent de gauche à droite, mais c'est dépendant du compilateur)
Pour être clair, il est indéterminé si l'appel à bar code> voit un argument vide ou non, et il n'y a pas d'UB.
@Mattmcnabb: Je ne suis pas très bon avec la hausse des langues, mais y a-t-il une différence? Je suppose qu'il existe une définition stricte de UB qui ne couvre pas cela, alors que je pense que cela serait intuitivement traité comme tel parce qu'il est indéterminé si l'argument est vide ou non.
"non spécifié" signifie qu'il existe un nombre fini d'options, mais l'un d'entre eux doit se produire et le programme produit; "Undefined" signifie que le programme a laissé le royaume de la sécurité définie entièrement et aucun comportement futur n'est fiable. donc ref
std :: Déplacer code> n'est pas une opération, il s'agit d'une référence à une référence de valeur R. L'opération de déplacement se produira à l'intérieur de l'autre
Baz code> constructeur. En conséquence, ce que vous faites devrait fonctionner. P>
Sans copie élision, le premier constructeur Baz d'argument effectue une construction de mouvement, ce qui peut arriver avant ou après la barre d'appel dans le deuxième argument. Donc le résultat n'est pas spécifié
Scott Meyers a mentionné un Similaire So question dans son poste