std::forward
exists because of a quirk in how &&
works under type deduction.
Under type deduction, the T
in T&&
will bind to one of 3 possibilities. If being deduced from an lvalue int&
, T
will bind to int&
. Then int& &&
is just a int&
. If being deduced from an lvalue int const&
, T
will bind to int const&
, and int const& &&
is int const&
. If being deduced from an rvalue int
of some kind, T
will bind to int
, and int&&
is int&&
.
std::forward
is a utility function to reverse that map. The three pertinent signatures of std::forward<>
are: T& std::forward<T&>(T&)
or T const& std::forward<T const&>(T const&)
or T&& std::forward<T>(T&&)
All of this ends up being exceedingly useful when doing the technique known as "perfect forwarding", where you use T&&t
in a type deduction context, then std::forward<T>(t)
to pass on the "same type" as was deduced from to another call.
Note that there are a few simplifying lies above. There are is also the possibility of T const&&
which is pretty obscure type-wise, as an example. I probably glossed over some details of how the type deduction works, and the terms rvalue
and lvalue
don't fully reflect the full 5-fold (or is it 6?) different kinds of variable values in C++11.