Я экспериментирую с Perfect Forwarding и обнаружил, что std::forward()
нуждается в двух перегрузках:
Перегрузка Nr. 1:
template <typename T>
inline T&& forward(typename
std::remove_reference<T>::type& t) noexcept
{
return static_cast<T&&>(t);
}
Перегрузка №2:
template <typename T>
inline T&& forward(typename
std::remove_reference<T>::type&& t) noexcept
{
static_assert(!std::is_lvalue_reference<T>::value,
"Can not forward an rvalue as an lvalue.");
return static_cast<T&&>(t);
}
Теперь типичный сценарий для Perfect Forwarding выглядит примерно так:
template <typename T>
void wrapper(T&& e)
{
wrapped(forward<T>(e));
}
Конечно, вы знаете, что когда экземпляр wrapper()
создается, T
зависит от того, является ли переданный ему аргумент lvalue или rvalue. Если это значение типа U
, T
выводится в U&
. Если это значение, T
выводится в U
В любом случае - в контексте wrapper()
- e
является lvalue, поэтому он всегда использует первую перегрузку std::forward()
.
Теперь мой вопрос:
Каков допустимый сценарий, в котором используется 2-я перегрузка (и она необходима)?