In the case that you do know that t will not be in a moved-from state after the call to f, your two somewhat sensible options are:
-
return
std::forward<T>(t)with typeT&&, which avoids any construction but allows for writing e.g.auto&& ref = wrapper(42);, which leavesrefa dangling reference -
return
std::forward<T>(t)with typeT, which at worst requests a move construction when the parameter is an rvalue — this avoids the above problem for prvalues but potentially steals from xvalues
In all cases you need std::forward. Copy elision is not considered because t is always a reference.