Я читаю запись std::forward
в cppreference.
Для второй перегрузки std::forward
есть пример:
template<class T> void wrapper(T&& arg) { foo(forward<decltype(forward<T>(arg).get())>(forward<T>(arg).get())); }
где тип
arg
может быть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 };
Но можно определить, является ли forward<T>(arg).get()
lvalue или rvalue без использования std::forward
(если аргумент wrapper
, относящийся к arg
, является lvalue, forward<T>(arg).get()
является lvalue; в противном случае это rvalue). Следующая программа является вспомогательной:
#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));
}
Итак, какая польза от внешнего std::forward
?
std::forward
. О том, зачем нужна вторая перегрузка, см., например. stackoverflow.com/questions/38344332/ а>. - person Holt   schedule 09.01.2017foo(int&)
, иfoo(int&&)
, здесь нет необходимости использовать переадресацию... - person Steeve   schedule 09.01.2017get() &&
уже должен возвращатьint &&
и использованиеreturn std::move(i);
внутри него на самом деле законно. - person W.F.   schedule 09.01.2017