When I was reading Effective Modern C++ by Scott Meyer about how std::forward function works, I got one question that I don't quite understand. Say if we have a function foo
as follows:
template<typename T>
void foo(T&& fooParam)
{
...
someFunc(std::forward<T>(fooParam));
}
In the book, Scott explains that the std::forward<T>
could be implemented in the following way:
template<typename T>
T&& forward(typename remove_reference<T>::type& param)
{
return static_cast<T&&>(param);
}
Suppose the argument passed to foo
is an rvalue of type Widget
. Then the std::forward
function template would be initialized like this:
Widget&& forward(Widget& param)
{ return static_cast<Widget&&>(param); }
So my question is, when fooParam
(which is of type Widget &&
) passed to std::forward
, how could the function that takes a parameter of type Widget& param
match fooParam
? I know fooParam
itself is a lvalue. But its type is still rvalue reference (Widget &&
) right? How could they match each other?
If a function which takes a parameter of lvalue reference type could be passed with a rvalue reference, then this function could do whatever it wants to even modify the passed in rvalue (like a temporary object). This doesn't make sense to me...