Я экспериментирую с Perfect Forwarding и обнаружил, что std::forward()
нужны две перегрузки:
Перегрузка №. 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. Если это lvalue типа U
, T
преобразуется в U&
. Если это значение r, T
преобразуется в U
.
В любом случае - в области wrapper()
- e
является lvalue, поэтому всегда используется первая перегрузка std::forward()
.
Теперь мой вопрос:
Каков допустимый сценарий, в котором используется вторая перегрузка (и она необходима)?
std::forward<int>(2)
. - person Raymond Chen   schedule 29.05.2019static_assert
предназначено для предотвращения некорректного использования API, а не для корректного сценария. - person Nicol Bolas   schedule 29.05.2019