6

Disons que j'ai une fonction:Les valeurs de retour vont-elles être passées par la référence rvalue dans C++ 0x?

typedef std::vector<int> VecType; 
VecType randomVector(); 

int processing() 
{ 
    VecType v = randomVector(); 
    return std::accumulate(v.begin(), v.end(), 0); 
} 

Est-ce que C++ 0x dire spécifiquement la copie parasite sera évitée de la valeur de retour de randomVector? Ou un compilateur aurait-il besoin de mettre en œuvre le RVO? Il me semble que la valeur randomVector() devrait être traitée comme un rvalue, et donc le constructeur de déplacement de v devrait être appelé, mais je ne suis pas complètement sûr que ce soit vrai.

+0

Pas une bonne question, à mon humble avis. La norme ne peut pas utilement indiquer ce qu'une mise en œuvre PEUT faire, seulement ce qu'elle DOIT faire. –

+0

En fait, dans l'exemple que vous avez donné Return Value Optimization est effectuée par la plupart des compilateurs ... Donc, il est efficace sans rvalue. De même, rvalue est plus important pour passer des arguments aux fonctions. – Artyom

+0

Le titre de la question est un peu trompeur. Votre fonction renvoie une valeur et non une référence. Mais une référence rvalue peut s'y lier, ce qui arrive si l'élision de la copie ne peut pas être effectuée pour une raison quelconque et que le type possède un constructeur de mouvement (Le paramètre du constructeur de déplacement est une référence rvalue) – sellibitze

Répondre

7

La règle est la suivante

  • Si le compilateur peut faire RVO, il est autorisé à le faire, et aucune copie et aucun mouvement est fait.
  • Sinon, le constructeur approprié est pris.

Comme vous dites, le temporaire est une rvalue, et donc le constructeur de déplacement est sélectionné, en raison d'une règle dans 13.3.3.2/3, qui dit qu'une référence rvalue se lie à un rvalue mieux qu'une référence lvalue. En décidant d'utiliser le déplacement ou le constructeur de copie, la résolution de surcharge va donc préférer le constructeur de déplacement.

La règle selon laquelle le compilateur est autorisé à effectuer RVO est écrite à 12.8/15.

2

Toutes les valeurs renvoyées sont considérées comme rvalues. Par conséquent, si le compilateur n'implémente pas RVO dans ce cas, il doit utiliser le constructeur de déplacement plutôt que le constructeur de copie.

+1

Je ne sais pas comment interpréter le "doit utiliser le mouvement". AFAIU, supposé un compilateur avec support U/NRVO, le flux de décision est le suivant: 1) si RVO-friendly, optimiser toute opération de déplacement/copie, 2) sinon si déplacer le construtor disponible, l'utiliser 3) else if copy constructeur disponible, utilisez-le 4) sinon programme mal formé – mloskot

+0

@mloskot Je veux dire que le constructeur de déplacement est sélectionné car c'est un meilleur ajustement pour la surcharge que le constructeur de copie. – Motti

+2

J'ai compris. L'hypothèse implicite que move ctor existe n'était pas claire pour moi. Comme move ctor est sélectionné, mais seulement s'il existe. – mloskot