[Avancé] référence « sur des transitoires » (r-value reference) et « déplacements » (move semantics)

[Avancé] référence « sur des transitoires » (r-value reference) et « déplacements » (move semantics)

par Jean-Cédric Chappelier,
Number of replies: 5

Pour ceux qui souhaitent aller plus loin (c'est vraiment hors niveau attendu du cours), la surcharge des opérateurs est le bon moment d'aborder (or revenir / creuser) la notion de « déplacement » (move semantics) et de références vers des transitoires (r-value references).

Pour ce que ça intéresse, j'avais rédigé une annexe à ce sujet en bas de la solution de l'exercice 3 de la série 7 du premier semestre. Je vous y renvoie et n'hésiter pas à poser vos questions dans ce fil de discussion.

In reply to Jean-Cédric Chappelier

Re: [Avancé] référence « sur des transitoires » (r-value reference) et « déplacements » (move semantics)

par Edouard Bernard Gérard de Ponnat,

Bonjour, je suis arrivé sur ce sous forum un peu par hasard, j'essayais de surcharger l'operateur:  std::ostream& operator<<

---------------------------

La definition de l'operateur est la suivante: std::ostream& operator<<(std::ostream& sortie, const Machin& x){return x.affichage(sortie) << x.afficher(sortie);}

Les methodes affichage et afficher retournent toute les deux des ostream& (pas de soucis je pense de ce point de vu la). 

------------------------------

J'ai été plutôt supris de voir dans un premier temps que le compilateur me disait:

error: no match for 'operator<<' (operand types are 'std::ostream {aka std::basic_ostream<char>}' and 'std::ostream {aka std::basic_ostream<char>}')|

Je me suis dis que c'etait bizzare qu'il me dise que deux choses identiques soient differentes.

Et puis dans un deuxième temps j'ai observe que j'avais egalement cette erreur la:

error: cannot bind 'std::ostream {aka std::basic_ostream<char>}' lvalue to 'std::basic_ostream<char>&&'|
Je me suis donc renseigne sur ce que pouvait être des l-value et r-value (je pense avoir brièvement compris) et j'ai ensuite vu que vous aviez ouvert ce forum. J'ai donc lu l'annexe que vous avez joint et essayé plusieurs des solutions proposées, mais j'ai toujours cette même erreur, ou bien d'autres erreurs en essayant d'utiliser &&.
J'aimerai bien comprendre ce qui conceptuellement ne fonctionne pas, car j'ai essayé avec des compilateurs plus ancien (98) qui ne me sortent pas cette erreur (conformément à ce qui est marqué dans l'annexe).
Merci beaucoup pour votre réponse.

In reply to Edouard Bernard Gérard de Ponnat

Re: [Avancé] référence « sur des transitoires » (r-value reference) et « déplacements » (move semantics)

par Edouard Bernard Gérard de Ponnat,

Ps: Ma question n'est pas tellement au niveau de la pratique car je peux facilement resoudre mon problème en utilisant des fonctions void plutôt que des ostream&. Je souhaite surtout savoir si il y a moyen de contourner ce probleme de

ostream& << ostream& avec les l-value et r-value.

Merci beaucoup

In reply to Edouard Bernard Gérard de Ponnat

Re: [Avancé] référence « sur des transitoires » (r-value reference) et « déplacements » (move semantics)

par Fares Ahmed,

A mon sens le problème ne vient pas de l-/r-values dans votre cas.


Si vous regardez votre première erreur, elle vous dit qu'elle ne trouve pas d’opérateur prenant deux ostream comme argument. Et en regardant votre surcharge d'opérateur, vous faites "x.affichage(sortie) << x.afficher(sortie)" ce qui équivaut à "operator<<(x.affichage(sortie), x.afficher(sortie))", votre erreur vient donc de là (pourquoi vous avez défini deux fonctions d'affichage différentes par ailleurs?). 

Avec ça en tête, vous devriez pouvoir corriger votre problème facilement (revoyiez les MOOCs si nécessaire pour de l'inspiration).

In reply to Fares Ahmed

Re: [Avancé] référence « sur des transitoires » (r-value reference) et « déplacements » (move semantics)

par Edouard Bernard Gérard de Ponnat,

Bonjour, merci beaucoup pour votre réponse. Sinon comme je l'ai écrit dans le Ps: j'avais résolu facilement le problème avec une fonction void. Mais comme l'erreur m'avait mise sur la piste de r/l-value je me demandais si il n'y avait pas quelque chose à faire avec.

In reply to Edouard Bernard Gérard de Ponnat

Re: [Avancé] référence « sur des transitoires » (r-value reference) et « déplacements » (move semantics)

par Jean-Cédric Chappelier,

Comme dit par Fares, votre problème n'a rien à voir avec [lr]-values, mais simplement que
x.affichage(sortie) << x.afficher(sortie);
n'a strictement aucun sens.
Vous semblez confondre valeur de retour et affichage.
De même que
return i;
est très différent de
cout << i;
,
return cout;
est très différent de
cout << cout;
(qui n'a aucun sens).