I am writing library which wraps a lot of functions and methods from other library. To avoid coping of return values I am applying std::forward
like so:
template<class T>
T&& wrapper(T&& t) {
f(t); // t passed as lvalue
return std::forward<T>(t);
}
f
returns void
and takes T&&
(or overloaded on valueness). Wrapper always returns wrappers's param and on returned value should preserve valuness of argument. Do I actually need to use std::forward
in return
? Does RVO makes it superfluous? Does the fact that it is a reference (R or L) makes it superfluous? Is it needed if return is not last function statement (inside some if)?
It is debatable if wrapper()
should return void
or T&&
, because caller have access to evaluated value via arg (which is reference, R or L). But in my case I need to return value so that wrapper()
can be used in expressions.
It might be irrelevant to the question, but it is known that functions f
does not steal from t
, so 1st use of std::forward
in f(std::forward<T>(t))
is superfluous and it was removed by me.
I've wrote small test: https://gist.github.com/3910503
Test shows, that returning unforwarded T
- does creates extra copy in gcc48 and clang32 with -O3 (RVO does not kicks in).
Also, I was not able to get bad behavior from UB in:
auto&& tmp = wrapper(42);
It does not prove anything of cause because it is undefined behavior (if it is UB).
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 type T&&
, which avoids any construction but allows for writing e.g. auto&& ref = wrapper(42);
, which leaves ref
a dangling reference
return std::forward<T>(t)
with type T
, 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.