Les opérateurs de conversion de valeur de retour déduits sont un peu étranges. Mais l'idée centrale est qu'il agit comme un paramètre de fonction pour choisir lequel est utilisé.
Et pour décider entre T&&
et T&
les T&
victoires dans les règles de résolution de surcharge. Ceci permet:
template<class T>
void f( T&& ) { std::cout << "rvalue"; }
template<class T>
void f( T& ) { std::cout << "lvalue"; }
travailler. T&&
peut correspondre à une valeur l, mais lorsque la surcharge lvalue et la référence universelle sont disponibles, la valeur lvalue est préférée.
Le bon ensemble d'opérateurs de conversion est probablement:
template <typename T>
operator T&&() &&;
template <typename T>
operator T &() const; // maybe &
ou même
template <typename T>
operator T() &&;
template <typename T>
operator T &() const; // maybe &
pour éviter que l'extension de vie échouée ne vous mord.
3 Les types utilisés pour déterminer l'ordre dépendent du contexte dans lequel l'ordre partiel est effectué:
[COUPER]
(3.2) Dans le contexte d'un appel à une fonction de conversion, les types de retour des modèles de fonction de conversion sont utilisés.
Ce qui finit alors par dépendre de règles "plus spécialisées" lors du choix des surcharges:
(9.1) si le type du modèle d'argument était une référence lvalue et que le type du modèle de paramètre ne l'était pas, le type de paramètre n'est pas considéré comme au moins aussi spécialisé que le type d'argument; autrement,
Ainsi, il operator T&&
n'est pas au moins aussi spécialisé que operator T&
, pendant ce temps, aucun état de règle operator T&
n'est pas au moins aussi spécialisé que operator T&&
, donc il operator T&
est plus spécialisé que operator T&&
.
Des modèles plus spécialisés gagnent moins de résolution de surcharge, toutes choses étant égales par ailleurs.