Почему std :: forward имеет две перегрузки?
Учитывая следующие ссылки свертывания правил
T& &
->T&
T&& &
->T&
T& &&
->T&
T&& &&
->T&&
Третье и четвертое правило подразумевают, чтоT(ref qualifer) &&
это преобразование идентичности, т.е.T&
остается вT&
а такжеT&&
остается вT&&
, Почему у нас есть две перегрузки дляstd::forward
? Разве следующее определение не может служить всем целям?
template <typename T, typename = std::enable_if_t<!std::is_const<T>::value>>
T&& forward(const typename std::remove_reference<T>::type& val) {
return static_cast<T&&>(const_cast<T&&>(val));
}
Здесь единственная цельconst std::remove_reference<T>&
служит не копировать. Иenable_if
помогает гарантировать, что функция вызывается только для неконстантных значений. Я не совсем уверен, чтоconst_cast
нужен, так как это не сама ссылка, которая является константой.
посколькуforward
всегда вызывается с явными параметрами шаблона, мы должны рассмотреть два случая:
forward<Type&>(val)
Здесь типT
вforward
будетT&
и, следовательно, возвращаемый тип будет преобразованием идентичности вT&
forward<Type&&>(val)
Здесь типT
вforward
будетT&&
и, следовательно, возвращаемый тип будет преобразованием идентичности вT&&
Итак, зачем нам две перегрузки, как описано вhttp://en.cppreference.com/w/cpp/utility/forward?
Заметка: Я не уверен, еслиstd::forward
когда-либо используется сconst
типа, но я отключилforward
в таком случае, потому что я никогда не видел, чтобы это использовалось так. Также в этом случае семантика перемещения не имеет смысла.