2011-08-26 3 views
1

J'ai 3 questions:Liaison de référence modifiable rvalue à lvalue modifiable

  1. Puis-je lier un lvalue directement à une référence rvalue? Qu'arrive-t-il à l'objet std::move()

  2. Quelle est la différence entre std :: move et std::forward?

struct myStr{ 
    int m_i; 
}; 

void foo(myStr&& rs) { } 

myStr rValueGene() 
{ 
    return myStr(); 
} 

int main() 
{ 
    myStr mS= {1}; 
    foo(rValueGene()); //ok passing in modifiable rvalue to rvalue reference 

    // To Question 1: 
    //below initilize rvalue reference with modifiable lvalue, should be ok 
    //but VS2010 gives a compile error: error C2440: 'initializing' : cannot convert from 'myStr' to 'myStr &&' 
    //Is this correct ? 
    myStr&& rvalueRef = mS; 

    //by using std::move it seems ok, is this the standard way of doing this 
    //to pass a lvalue to rvalue reference 
    //myStr&& rvalueRef = std::move(mS); 

    // To Question 2:  
    //also what happens to mS object after std::move ? 
    //destroyed , undefined ? 
} 

Répondre

3

1> Puis-je lier un lvalue directement à une référence rvalue?

Pas sans une distribution explicite (ie: std::move).

2> Qu'arrive-t-il à l'objet std :: move()?

Rien jusqu'à ce qu'il soit réellement déplacé. Tout std::move est de renvoyer une référence de valeur r à ce que vous lui avez donné. Le déplacement réel se produit dans le constructeur de mouvement/affectation du type en question.

3> Quelle est la différence entre std :: move et std :: forward?

std::move est destiné à déplacer; std::forward est pour l'expédition. Cela semble glib, mais c'est l'idée. Si vous avez l'intention de déplacer un objet, utilisez std::move. Si vous avez l'intention de transférer un objet, utilisez std::forward.

Le transfert utilise une sémantique spécialisée qui permet des conversions entre les types de références, de sorte que les natures de référence sont préservées entre les appels. Les détails de tout cela sont très ... techniques.

std::movetoujours retourne un & &. Si vous lui donnez une référence de valeur l, elle renvoie une référence de valeur r. Si vous lui donnez un type de valeur, il renvoie une référence de valeur r à cette valeur. Et ainsi de suite.

std::forward ne fait pas revenir toujours un & &. Syntaxiquement, std::forward fait juste un static_cast<T&&>.Cependant, en raison de la syntaxe spécialisée autour de la conversion en types & &, cette conversion ne renvoie pas toujours un & &. Oui, c'est bizarre, mais cela résout le problème d'expédition, donc personne ne s'en soucie. C'est pourquoi il est contenu dans std::forward, plutôt que d'avoir à faire explicitement le static_cast vous-même.

1

Question 1. Oui, le compilateur est correct.

Question 2. Rien ne se passe. std::move jette juste des choses à des valeurs.

Si toutefois vous deviez utiliser std::move pour passer mS (ou myStr) à foo, alors cette fonction peut supposer qu'il peut « voler » l'objet et ainsi mS pourrait se retrouver dans un état non précisé après l'appel de fonction.

Questions connexes