When will C ++ 11 run automatically, when std :: move is not explicitly used?

If I have a struct in which I did not provide a copy and move constructor:

 struct MyStruct { MyStruct() { // this is the only function ... } ... }; 

then if I do the following:

 std::vector<MyStruct> vec; ... vec.push_back(MyStruct()); 

instead of std::move() as shown below:

 vec.push_back(std::move(MyStruct())); 

Will C ++ 11 do the move of my temporary variable? Or, how can I be sure that this will be a move instead of a copy?

+6
source share
5 answers

In C ++ 11, std::vector::push_back will use the move constructor if rvalue is passed (and there is a move constructor for the type), but you should also consider using std::vector::emplace_back in such situations; std::vector::emplace_back will build the object instead of moving it.

+10
source

Will C ++ 11 do the move of my temporary variable? Or, how can I be sure that this will be a move instead of a copy?

It depends. it

 vec.push_back(MyStruct()); 

binds to

 std::vector<MyStruct>::push_back(MyStruct&&); 

but the rvalue is transferred or copied, it completely depends on whether MyStruct has a move move constructor (similarly for assigning a move).

It won't make any difference if you call

 vec.push_back(std::move(MyStruct())); 

since MyStruct() already an rvalue.

So it really depends on the details of MyStruct . There is simply not enough information in your question to find out if your class has a move constructor.

These are the conditions that must be met in order for the class to have an implicitly generated move constructor:

  • non-declared copy constructors
  • unassigned copy assignment operators
  • unassigned move assignment operators
  • undeclared destructors

Of course, you can always provide your own if any of these conditions are not met:

 MyStruct(MyStruct&&) = default; 
+7
source

Since MyStruct() will create an rvalue, T && overload will be called.

It is actually very simple to check ( demo ):

 #include <iostream> struct A{ int x; }; void foo(A &&x){ std::cout<<"&&" <<std::endl; } void foo(A &x){ std::cout<<"&" <<std::endl; } int main() { foo(A()); // prints && A a; foo(a); // prints & return 0; } 

To clarify: I didn't mention anything about the move constructor, because you might have an explicitly remote move mechanism, and yet T && will be called.

For example ( demo ):

 #include <iostream> struct A{ int x; A() = default; A(const A& ) = default; A(A&&) = delete; }; /* ^ no move ctor */ void foo(A &&x){ std::cout<<"&&" <<std::endl; } void foo(A &x){ std::cout<<"&" <<std::endl; } int main() { foo(A()); //still prints && A a; foo(a); return 0; } 

As I said, this is because this value ...

+4
source

Yes, it will use push_back (T && value) and move the value.

+1
source

If the type moves, then it will definitely be. Typically, the standard compiler should always choose move semantics to copy semantics, if any.

+1
source

Source: https://habr.com/ru/post/973402/


All Articles