Por que std :: forward tem duas sobrecargas?
Dadas as seguintes regras de recolhimento de referência
T& &
->T&
T&& &
->T&
T& &&
->T&
T&& &&
->T&&
A terceira e quarta regra implicam queT(ref qualifer) &&
é a transformação da identidade, ou seja,T&
permanece emT&
eT&&
permanece emT&&
. Por que temos duas sobrecargas parastd::forward
? A definição a seguir não poderia servir a todos os propósitos?
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));
}
Aqui o único objetivo doconst std::remove_reference<T>&
serve é não fazer cópias. E aenable_if
ajuda a garantir que a função seja chamada apenas em valores não const. Não tenho muita certeza se oconst_cast
é necessário, pois não é a própria referência que é const.
Desde aforward
é sempre chamado com parâmetros explícitos do modelo, há dois casos que precisamos considerar:
forward<Type&>(val)
Aqui o tipo deT
noforward
seráT&
e, portanto, o tipo de retorno será a transformação de identidade emT&
forward<Type&&>(val)
Aqui o tipo deT
noforward
seráT&&
e, portanto, o tipo de retorno será a transformação de identidade emT&&
Então, por que precisamos de duas sobrecargas, conforme descrito emhttp://en.cppreference.com/w/cpp/utility/forward?
Nota: Não tenho certeza sestd::forward
é sempre usado comconst
tipos, mas eu desabiliteiforward
nesse caso, porque nunca o vi usado assim. Também a semântica de movimento também não faz sentido nesse caso.