I'd really like to finally get to understand this. Let's say std::forward
is defined like this:
template<class T>
T&& forward(typename std::remove_reference<T>::type& t) noexcept {
return static_cast<T&&>(t);
}
template <class T>
T&& forward(typename std::remove_reference<T>::type&& t) noexcept {
return static_cast<T&&>(t);
}
We have a function:
template <typename T>
void I_forward_arguments(T&& arg)
{
forward<T>(arg);
}
I_forward_arguments(5);
I pass 5, which is an rvalue, and T
in I_forward_arguments()
is int
type. It then calls forward
with explicit template argument of int
, meaning the call is no longer a deduced context and there are no universal references, and the two choices of functions to call are:
template<class T>
int&& forward(typename std::remove_reference<int>::type& t) noexcept {
return static_cast<int&&>(t);
}
template <class T>
T&& forward(typename std::remove_reference<int>::type&& t) noexcept {
return static_cast<T&&>(t);
}
which when we remove the reference we end up with one taking an int&
and another taking an int&&
. Since the argument in I_forward_arguments
is ALWAYS an lvalue, I don't understand how it gets through to the function taking the int&&
version of forward
. Can someone please explain this? I've spent a long time trying to figure it out.