std::move

std::move - C++ - Programmation

Marsh Posté le 26-04-2009 à 15:39:24    

Hi,
 

Code :
  1. class Derived
  2.     : public Base
  3. {
  4.     std::vector<int> vec;
  5.     std::string name;
  6.     // ...
  7. public:
  8.     // ...
  9.     // move semantics
  10.     Derived(Derived&& x)              // rvalues bind here
  11.         : Base(std::move(x)),
  12.           vec(std::move(x.vec)),
  13.           name(std::move(x.name)) { }
  14.     Derived& operator=(Derived&& x)   // rvalues bind here
  15.     {
  16.         Base::operator=(std::move(x));
  17.         vec  = std::move(x.vec);
  18.         name = std::move(x.name);
  19.         return *this;
  20.     }
  21.     // ...
  22. };


 
Dans ce genre de code std::move est utilisé dans le constructeur de move par exemple pour initialiser la variable name, ma question est pourquoi?
Le fait que x soit une rvalue n'implique pas que x.name en soit une ?

Reply

Marsh Posté le 26-04-2009 à 15:39:24   

Reply

Marsh Posté le 29-04-2009 à 17:35:11    

:bounce:

Reply

Marsh Posté le 29-04-2009 à 19:20:30    

un membre de rvalue ne peut etre qu'une rvalue lui même hein [:dawa]

Reply

Marsh Posté le 29-04-2009 à 19:43:54    

c'est ce qui me parraissait le plus logique en effet, mais alors pourquoi faire du std::move ici ?

Reply

Marsh Posté le 29-04-2009 à 20:05:50    

bah car tu peut guère faire autrechose sur une rvalue :o

Reply

Marsh Posté le 29-04-2009 à 20:21:27    

mais le move à la base ça sert à rendre une lvalue rvalue, donc si c déjà une rvalue pourquoi mover??

Reply

Marsh Posté le 29-04-2009 à 20:41:02    

move preserve la rvalueness d'une rvalue. Qui te dit qu'un de membres là n'a pas lui même un constructeur par move. Si tu passais x.name par lvlaue, il en tomberais pas ou il faut.

Reply

Marsh Posté le 29-04-2009 à 20:48:49    

sauf que x est forcément une r-value, car on est à cet endroit dans le constructeur de move de x.


Message édité par Glock 17Pro le 29-04-2009 à 20:49:05
Reply

Marsh Posté le 29-04-2009 à 21:43:10    

je parle des move-constructor de base, vec et name ...

Reply

Marsh Posté le 30-04-2009 à 00:20:46    

oui mais - sauf si on ne se comprend pas- , si on est sûr que x est une r-value, si comme tu me la confirmer "un membre de rvalue ne peut etre qu'une rvalue lui même" et bien je ne vois toujours pas l'intérêt de faire du move par exemple là :  
 
 
 
vec(std::move(x.vec)) : x est r-value=> x.vec est r-value,  so why move ??
 
 
EDIT: à priori l'explication serait que, bien que déclaré comme r-value parameter,  x est traité comme l-value pour des raisons de sécurité, si quelqu'un en sait d'avantage je suis preneur
 
void g(const A& );
void g(A&& );
 
void f(A&& a)
{
 
    g(a);  // calls g(const A& )
}
 
à priori c'est pour éviter des histoires de double move et donc de contenu "voler" deux fois


Message édité par Glock 17Pro le 30-04-2009 à 13:40:58
Reply

Marsh Posté le 30-04-2009 à 00:20:46   

Reply

Marsh Posté le 12-01-2012 à 10:57:25    

car une named rvalue est une lvalue


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

Reply

Marsh Posté le 12-01-2012 à 19:58:34    

voial des qu'une rvaleu a un nom, ca devient une lvalue

Reply

Marsh Posté le 14-01-2012 à 19:36:48    

de plus il me semble qu'il vaut mieux se contenter dans la pluspart des cas d'un operateur d'assignement par value et qui swap plutot que d'en déclarer un prenant une rvalue reference
 

Code :
  1. struct Test { };
  2. void g(Test && p) { std::cout << "&&"; }
  3. template<class TQ>
  4. void f(TQ&& t)
  5. {
  6. g( std::forward<TQ>(t) );
  7. }
  8. int main()
  9. Test t;
  10. f(t);
  11. std::cin.ignore();
  12. }


Message édité par weblook$$ le 08-05-2012 à 20:31:44

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

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed