As stated in cplusplus.com , std::forward has two signatures:
template <class T> T&& forward (typename remove_reference<T>::type& arg) noexcept; template <class T> T&& forward (typename remove_reference<T>::type&& arg) noexcept;
A typical use of std::forward is to preserve rvalueness when passing arguments to other functions. We illustrate this with an example:
void overloaded(int &) { std::cout << "lvalue"; } void overloaded(int &&) { std::cout << "rvalue"; } template <typename T> void fwd(T && t) { overloaded(std::forward<T>(t)); }
When we call fwd(0) , T prints int ( T is of type int && ). Then we will call std::forward<int>(t) . The result of this call is an expression of type int && , so the second version of the overloaded function is selected, and the program outputs "rvalue" to standard output.
When we call fwd(i) (where I am some int variable), T prints int& ( T is of type int & ). Then we will call std::forward<int&>(t) . The result of this call (after applying the rules for dropping links) is an expression of type int & , therefore, the first version of the overloaded function is selected, and the program outputs "lvalue" to standard output.
In both cases, we use the first overload std::forward (accepting typename remove_reference<T>::type& arg ). This is because even if the type T is int && , it binds to the lvalue reference (because the named variable of type "rvalue reference to something" itself is an lvalue and lvalues ββcannot bind to the rvalue reference).
Question 1:
What is the second overload of std::forward for? Can you come up with some practical example that uses an overload that takes arg by rvalue reference?
Question 2:
cplusplus.com says:
Both signatures return the same as:
static_cast<decltype(arg)&&>(arg)
The problem I am facing is that I am sure that this is not correct. When we try to return this from the first std::forward overload, we get a compilation error.
When fwd is called with int rvalue, it calls the first overload of std::forward with T = int . Then decltype(arg) will become int& , so static_cast<decltype(arg)&&>(arg) will crash to static_cast<int&>(arg) . But the return type is int && , and we get a compilation error:
cannot bind 'std::remove_reference<int>::type {aka int}' lvalue to 'int&&'
Both overloaded versions of std::forward should return static_cast<T&&>(arg) . I'm right?
Do you think that a quote from cplusplus.com is a mistake?