Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What does the standard library guarantee about self move assignment?

What does the C++11 standard say about self move assignment in relation to the standard library? To be more concrete, what, if anything, is guaranteed about what selfAssign does?

template<class T> std::vector<T> selfAssign(std::vector<T> v) {   v = std::move(v);   return v; } 
like image 832
Bjarke H. Roune Avatar asked Oct 29 '12 18:10

Bjarke H. Roune


People also ask

How does STD move work?

std::move is used to indicate that an object t may be "moved from", i.e. allowing the efficient transfer of resources from t to another object. In particular, std::move produces an xvalue expression that identifies its argument t . It is exactly equivalent to a static_cast to an rvalue reference type.

Does STD copy move?

std::move is actually just a request to move and if the type of the object has not a move constructor/assign-operator defined or generated the move operation will fall back to a copy.

Which is true about move operations move constructor move assignment operator?

The move assignment operator is different than a move constructor because a move assignment operator is called on an existing object, while a move constructor is called on an object created by the operation. Thereafter, the other object's data is no longer valid.

Does std :: move CALL move assignment?

We know that std::move does not actually move anything. It just cast an lvalue reference (&) to rvalue reference (&&).


1 Answers

17.6.4.9 Function arguments [res.on.arguments]

1 Each of the following applies to all arguments to functions defined in the C++ standard library, unless explicitly stated otherwise.

...

  • If a function argument binds to an rvalue reference parameter, the implementation may assume that this parameter is a unique reference to this argument. [ Note: If the parameter is a generic parameter of the form T&& and an lvalue of type A is bound, the argument binds to an lvalue reference (14.8.2.1) and thus is not covered by the previous sentence. — end note ] [ Note: If a program casts an lvalue to an xvalue while passing that lvalue to a library function (e.g. by calling the function with the argument move(x)), the program is effectively asking that function to treat that lvalue as a temporary. The implementation is free to optimize away aliasing checks which might be needed if the argument was anlvalue. —endnote]

So, the implementation of std::vector<T, A>::operator=(vector&& other) is allowed to assume that other is a prvalue. And if other is a prvalue, self-move-assignment is not possible.

What is likely to happen:

v will be left in a resource-less state (0 capacity). If v already has 0 capacity, then this will be a no-op.

Update

The latest working draft, N4618 has been modified to clearly state that in the MoveAssignable requirements the expression:

t = rv 

(where rv is an rvalue), t need only be the equivalent value of rv prior to the assignment if t and rv do not reference the same object. And regardless, rv's state is unspecified after the assignment. There is an additional note for further clarification:

rv must still meet the requirements of the library component that is using it, whether or not t and rv refer to the same object.

like image 148
Howard Hinnant Avatar answered Sep 25 '22 21:09

Howard Hinnant