What is the right approach to handle that transparently from the caller of foo ?
You cannot do that, and that's intended to be so. An lvalue is never moved from transparently.
Since a moved-from object is usually left in an unknown (yet legal) state, it would be dangerous if a client could pass an lvalue as the argument to a function, and that function were allowed to silently move from it. The client may be left with a zombie object without even knowing it!
Therefore, the language enforces the rule that moving from an lvalue must be a conscious action, and shall occur by explicitly turning the lvalue into an rvalue (actually, an xvalue) through a call to std::move()
.
In this case, I would say your function foo()
- whatever it is actually supposed to do - should take an rvalue reference, and the client should invoke it like so:
T t2 = foo(std::move(t1));
Notice, that this last suggestion may not be correct once you turn a meaningless name such as foo()
into something that reflects the semantics of some particular operation in some concrete program. Without knowing what is the meaning of that operation, however, I can only provide formal, mechanical advice on how to make your code snippet compile, and how to think about move semantics in general.