Search code examples
c++c++11stlmove

C++ 11 - Is moving non local variable safe?


Say I have a function which goes like:

void a_fct( std::vector<double> &some_vector )
{
  std::vector<double> a_temporary_vector = some_vector;

  ... some stuff involving only a_temporary_vector ...

  some_vector = a_temporary_vector;
}

which is of course a bit silly, but it is just intended as bringing the following general questions:

  • It seems to me that one should rather move a_temporary_vector into some_vector here, as it then goes out of scope. But is it safe to move some_vector into a_temporary_vector rather than copying ?

  • Imagine now that somewhere else in the code, I have a pointer to the vector given as argument here. Is this pointer still pointing to it if I move some_vector into a_temporary_vector ?

In both cases, can I expect it to be true for any STL implementation ?


Solution

  • The standard (in 17.6.5.15) says:

    Objects of types defined in the C++ standard library may be moved from (12.8). Move operations may be explicitly specified or implicitly generated. Unless otherwise specified, such moved-from objects shall be placed in a valid but unspecified state.

    Thus, some_vector is required to have an (unspecified but) valid state after being moved from. You're allowed to move from it into you temporary and then move again from the temporary into some_vector.

    std::vector<double> a_temporary_vector = std::move(some_vector);
    // do stuff only on a_temporary_vector but not some_vector
    some_vector = std::move(a_temporary_vector);
    

    Pointers and references to some_vector itself are still valid but pointers or references to content of some_vector are not (as you would normally expect when passing an object to a function taking a non-constant reference).

    Note: You could use swap in this case instead if you're not sure about whether to move from it or not.

    void foo( std::vector<double> &some_vector )
    {
      // swap contents of some_vector into temporary
      std::vector<double> a_temporary_vector;
      a_temporary_vector.swap(some_vector);
    
      // operate on temporary
    
      // swap content back into some_vector
      a_temporary_vector.swap(some_vector);
      some_vector = a_temporary_vector;
    }