web-dev-qa-db-fra.com

Existe-t-il une différence entre les références universelles et les références de transfert?

Un argument de cette fonction se liera à une référence rvalue:

void f(int && i);

Cependant, un argument de cette fonction se liera à une référence rvalue ou lvalue:

template <typename T>  
void f(T && t);

J'ai souvent entendu parler de référence universelle.
J'ai également entendu dire qu'il s'agissait d'une référence de transfert.
Signifient-ils la même chose?
S'agit-il uniquement d'une référence de transfert si le corps de la fonction appelle std::forward?

33
Trevor Hickey

Signifient-ils la même chose?

Référence universelle était un terme inventé par Scott Meyers pour décrire le concept de prendre une référence rvalue à un paramètre de modèle non qualifié de cv, qui peut ensuite être déduit comme une valeur ou une référence lvalue.

À l'époque, la norme C++ n'avait pas de terme spécial pour cela, ce qui était une erreur dans C++ 11 et le rend difficile à enseigner. Cette erreur a été corrigée par N4164 , qui a ajouté la définition suivante à [temp.deduct] :

Une référence de transfert est une référence rvalue à un paramètre de modèle non qualifié par cv. Si P est une référence de transfert et que l'argument est une valeur l, le type "référence lvalue vers A" est utilisé à la place de A pour la déduction de type.

Par conséquent, les deux signifient la même chose, et le terme standard C++ actuel est la référence de transfert. Le document lui-même explique pourquoi "renvoi de référence" est un meilleur terme que "référence universelle".

S'agit-il uniquement d'une référence de transfert si le corps de la fonction appelle std::forward?

Non, ce que vous faites avec une référence de transfert n'a pas d'importance pour le nom. La référence de transfert de concept fait simplement référence à la façon dont le type T est déduit dans:

template <class T> void foo(T&& ); // <== 

Il n'a pas besoin d'être transmis ultérieurement.

42
Barry

Malheureusement, c'est déroutant, mais ce ne sont que deux noms pour la même chose.
La référence universelle a été proposée (je suppose) par Meyers il y a longtemps (voir ici comme exemple).
La référence de transfert est récupérée directement à partir de standardese . C'est tout.

14
skypjack