decltype
est une manière de spécifier un type : Vous lui donnez une expression, et decltype
vous renvoie un type qui correspond au type de l'expression, comme expliqué dans [dcl.type.simple] p4:
Le type dénoté par decltype(e)
est défini comme suit :
- si
e
est une id-expression non parenthésée ou un accès à un membre de classe non parenthésé ([expr.ref]), decltype(e)
est le type de l'entité nommée par e
. S'il n'y a pas d'entité correspondante, ou si e
nomme un ensemble de fonctions surchargées, le programme est mal formé;
- sinon, si
e
est un xvalue, decltype(e)
est T&&
, où T
est le type de e
;
- sinon, si
e
est un lvalue, decltype(e)
est T&
, où T
est le type de e
;
- sinon,
decltype(e)
est le type de e
.
Remarquez que le premier point couvre decltype(a)
, et les points suivants traitent les cas de double parenthèses comme decltype((b))
.
En combinant ces règles avec les règles de réduction des références, vous pouvez donner un sens à decltype(e) &&
, qui est toujours une référence "appropriée". (C++14 ajoute également decltype(auto)
pour vous donner la déduction de type de auto
combinée avec la sémantique de catégorie de valeur de decltype
.)
Exemples
int foo();
int n = 10;
decltype(n) a = 20; // a est un "int" [id-expression non parenthésée]
decltype((n)) b = a; // b est un "int &" [(n) est un lvalue]
decltype((std::move(n))) c = a; // c est un "int &&" [(std::move(n)) est un xvalue]
decltype(foo()) d = foo(); // d est un "int" [(foo()) est un prvalue]
decltype(foo()) && r1 = foo(); // int &&
decltype((n)) && r2 = n; // int & [& && se réduit en &]
Il peut être utile de souligner la différence entre auto
et decltype
: auto
fonctionne sur des types, et decltype
fonctionne sur des expressions.
Vous ne devriez pas voir ou utiliser decltype
dans la programmation "quotidienne". Il est surtout utile dans du code de bibliothèque générique (à base de modèles), où l'expression en question n'est pas connue et dépend d'un paramètre. (En revanche, auto
peut être utilisé généreusement un peu partout.) En bref, si vous débutez en programmation, vous n'aurez probablement pas besoin d'utiliser decltype
pendant un certain temps.