4

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 be

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
};

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));
}

Running Result

So what is the use of the outer std::forward?

xskxzr
  • 12,442
  • 12
  • 37
  • 77
  • I think this is simply a poorly written example, just to demonstrate the use of the second `std::forward` overload. As to why the second overload is needed, see e.g. http://stackoverflow.com/questions/38344332/why-does-stdforward-have-two-overloads. – Holt Jan 09 '17 at 09:52
  • I think when you have both `foo(int&)` and `foo(int&&)` implemented, there is no need here to use forward... – Steeve Jan 09 '17 at 09:59
  • in my understanding `get() &&` should already return `int &&` and the use of `return std::move(i);` inside it is actually legit. – W.F. Jan 09 '17 at 11:21
  • @Holt better example would be welcome (as long as it's not distractingly long) – Cubbi Jan 09 '17 at 13:54

0 Answers0