Dato il seguente riferimento collasso regolePerché std :: forward ha due sovraccarichi?
T& &
->T&
T&& &
->T&
T& &&
->T&
T&& &&
->T&&
L' terza e quarta regola Ciò implica che T(ref qualifer) &&
è la trasformazione dell'identità, ovvero T&
rimane allo T&
e T&&
rimane allo T&&
. Perché abbiamo due sovraccarichi per std::forward
? La seguente definizione non può servire a tutti gli scopi?
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));
}
Qui l'unico scopo della const std::remove_reference<T>&
serve è quello di non fare copie. E lo enable_if
garantisce che la funzione venga richiamata solo su valori non const. Non sono completamente sicuro se sia necessario lo const_cast
poiché non è il riferimento stesso che è const.
Dal forward
è sempre chiamato con parametri di modello espliciti ci sono due casi dobbiamo considerare:
forward<Type&>(val)
Ecco il tipo diT
inforward
saràT&
e quindi il tipo di ritorno sarà la trasformazione identitàT&
forward<Type&&>(val)
Qui il tipo diT
inforward
saràT&&
e quindi il tipo di ritorno è la trasformazione di identitàT&&
Allora, perché abbiamo bisogno di due sovraccarichi come descritto in http://en.cppreference.com/w/cpp/utility/forward?
Nota: io non sono sicuro se std::forward
utilizza sempre con const
tipi, ma io disabile forward
in quel caso, perché non ho mai visto usato in quel modo. Anche spostare la semantica non ha davvero senso in quel caso.
Becuase rvalue non può essere associato a 'val' se non c'è il 2o sovraccarico? – songyuanyao
@songyuanyao whoops, ho avuto un const in là prima, ma in qualche modo ho deciso di rimuoverlo ... – Curious
L'esempio che dai non può essere associato a rvalue (vedi [questo esempio] (http://coliru.stacked-crooked.com/ a/b0ae1eaf909513e0)) – Rerito