11

Dire que j'ai la fonction suivantePourquoi le déplacement en C++ ne construit-il pas de références rvalue par défaut?

void doWork(Widget && param) // param is an LVALUE of RRef type 
{ 
    Widget store = std::move(param); 
} 

Pourquoi ai-je besoin de jeter param revenir à un rvalue avec std::move()? Ne devrait-il pas être évident que le type de param est rvalue puisqu'il a été déclaré dans la signature de la fonction comme une référence rvalue? Le constructeur de déplacement ne devrait-il pas être automatiquement invoqué ici sur ce seul principe?

Pourquoi cela ne se produit-il pas par défaut?

Répondre

22

avec votre conception:

void doWork(Widget && param) 
{ 
    Widget store1 = param;  // automatically move param 
    Widget store2 = param;  // boom 

    Widget store_last = param; // boom  
} 

avec la conception actuelle:

void doWork(Widget && param) 
{ 
    Widget store1 = param;    // ok, copy 
    Widget store2 = param;    // ok, copy 

    Widget store_last = std::move(param); // ok, param is moved at its last use 
} 

Ainsi, la morale ici est que même si vous avez une référence rvalue vous avez un nom pour ce qui signifie que vous pouvez utiliser plusieurs fois. En tant que tel, vous ne pouvez pas le déplacer automatiquement car vous pourriez en avoir besoin pour un usage ultérieur.

+0

Oh, je vois. Cela a du sens! Je suis d'accord, le design de la copie est toujours plus sûr que le mouvement implicite! – barney

+0

@barney ce moment où un exemple simple vous fait partir "Oh, je vois, ça a du sens!" Content de pouvoir en fournir un. – bolov

+0

Id luttent vraiment pour trouver du vrai code qui fait cela cependant, et encore plus un compilateur ne pourrait pas détecter et traiter comme une erreur. Y a-t-il eu des discussions sur la proposition concernant les compromis relatifs, ou y a-t-il une situation qui est beaucoup plus susceptible de se produire? –