It depends on what you do in foo()
:
Inside foo()
, if you store the argument in some internal storage, then yes it does matter, from readability point of view, because it is explicit at the call site that this particular argument is being moved and it should not be used here at call site, after the function call returns.
If you simply read/write its value, then it doesn't matter. Note that even if you pass by T&
, the argument can still be moved to some internal storage, but that is less preferred approach — in fact it should be considered a dangerous approach.
Also note that std::move
does NOT actually move the object. It simply makes the object moveable. An object is moved if it invokes the move-constructor or move-assignment:
void f(X && x) { return; }
void g(X x) { return; }
X x1,x2;
f(std::move(x1)); //x1 is NOT actually moved (no move constructor invocation).
g(std::move(x2)); //x2 is actually moved (by the move-constructor).
//here it is safe to use x1
//here it is unsafe to use x2
Alright it is more complex than this. Consider another example:
void f(X && x) { vec_storage.push_back(std::move(x)); return; }
void g(X x) { return; }
X x1,x2;
f(std::move(x1)); //x1 is actually moved (move-constructor invocation in push_back)
g(std::move(x2)); //x2 is actually moved (move-constructor invocation when passing argument by copy).
//here it is unsafe to use x1 and x2 both.
Hope that helps.