I'm reading the std::forward
entry in cppreference.
For the second overload of std::forward
, there is an example:
template<class T> void wrapper(T&& arg) { foo(forward<decltype(forward<T>(arg).get())>(forward<T>(arg).get())); }
where the type of
arg
may bestruct Arg { int i = 1; int get() && { return i; } // call to this overload is rvalue int& get() & { return i; } // call to this overload is lvalue };
But whether forward<T>(arg).get()
is lvalue or rvalue can be distinguished without the use of std::forward
(If the argument of wrapper
referring to arg
is lvalue, forward<T>(arg).get()
is lvalue; otherwise it is rvalue). The following program is a support:
#include <iostream>
#include <utility>
struct Arg
{
int i = 1;
int get() && { return i; } // call to this overload is rvalue
int& get() & { return i; } // call to this overload is lvalue
};
void foo(int&) {std::cout << "lvalue\n";}
void foo(int&&) {std::cout << "rvalue\n";}
template<class T>
void wrapper(T&& arg)
{
foo(std::forward<T>(arg).get()); // without the use of outer forward
}
int main()
{
Arg arg;
wrapper(arg);
wrapper(static_cast<Arg&&>(arg));
}
So what is the use of the outer std::forward
?