Your colleagues fear is without reason, the snippet shown does not suffer from undefined behavior.
The snippet written, since std::vector
is a class, is equivalent of the below, and since a function parameter must have a value before the function is called it's equivalent of first calling std::move
, then pushIt
, and later vec.operator=
.
When viewed in this way it's quite clear that it's actually safe to write such code as you have done.
vec.operator= (pushIt (std::move (vec));
In general
a = do_something (a);
I've met developers who get worried about such snippets because =
isn't a sequence-point; what if do_something
modifies a
, what happens to the left-hand side?
long story short; It doesn't matter. Even though we don't know in which order the left-hand side and the right-hand side will be evaluated it is well-defined in terms of correctness.
The left-hand side of =
is an lvalue, which can be seen as a location of where a certain value will end up. No matter the value stored at this location, the actual location will always be the same.
The right-hand side will, in this case, move from vec
. This will indoubtely change the value of vec
, but it won't change the location of where vec
is; so the result of the right-hand side will correctly be assigned to where it's supposed to.
Note: The actual assignment is sequenced, both lhs and rhs must be evaluated before this takes place (ie. before the value of rhs is assigned to the location yield by lhs), but the order of which lhs and rhs is evaluated is not set in stone.