Remarque
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de modifier des répertoires.
Le decltype spécificateur de type génère le type d’une expression spécifiée. Le decltype spécificateur de type, avec le auto mot clé, est utile principalement aux développeurs qui écrivent des bibliothèques de modèles. Utilisez et decltype déclarez auto un modèle de fonction dont le type de retour dépend des types de ses arguments de modèle. Vous pouvez également utiliser auto et decltype déclarer un modèle de fonction qui encapsule un appel à une autre fonction, puis retourne le type de retour de la fonction encapsulée.
Syntaxe
decltype(expression)
Paramètres
expression
Expression. Pour plus d’informations, consultez expressions.
Valeur retournée
Type du expression paramètre.
Remarques
Le decltype spécificateur de type est pris en charge dans Visual Studio 2010 ou versions ultérieures et peut être utilisé avec du code natif ou managé.
decltype(auto) (C++14) est pris en charge dans Visual Studio 2015 et versions ultérieures.
Le compilateur utilise les règles suivantes pour déterminer le type du expression paramètre.
Si le
expressionparamètre est un identificateur ou un accès membre de classe,decltype(expression)est le type de l’entité nommée parexpression. S’il n’existe aucune entité de ce type ou si leexpressionparamètre nomme un ensemble de fonctions surchargées, le compilateur génère un message d’erreur.Si le
expressionparamètre est un appel à une fonction ou à une fonction d’opérateur surchargée,decltype(expression)est le type de retour de la fonction. Les parenthèses autour d’un opérateur surchargé sont ignorées.Si le
expressionparamètre est une valeur rvalue,decltype(expression)est le type deexpression. Si leexpressionparamètre est un lvalue,decltype(expression)est une référence lvalue au type deexpression.
L’exemple de code suivant illustre certaines utilisations du spécificateur de decltype type. Tout d’abord, supposons que vous avez codé les instructions suivantes.
int var;
const int&& fx();
struct A { double x; };
const A* a = new A();
Ensuite, examinez les types retournés par les quatre decltype instructions du tableau suivant.
| Déclaration | Catégorie | Remarques |
|---|---|---|
decltype(fx()); |
const int&& |
Référence rvalue à un const int. |
decltype(var); |
int |
Type de variable var. |
decltype(a->x); |
double |
Type de l’accès au membre. |
decltype((a->x)); |
const double& |
Les parenthèses internes entraînent l’évaluation de l’instruction en tant qu’expression au lieu d’un accès membre. Et parce qu’il a est déclaré comme pointeur const , le type est une référence à const double. |
decltype et auto
En C++14, vous pouvez utiliser decltype(auto) sans type de retour de fin pour déclarer un modèle de fonction dont le type de retour dépend des types de ses arguments de modèle.
En C++11, vous pouvez utiliser le spécificateur de type sur un type de retour de fin, avec le auto mot clé, pour déclarer un modèle de fonction dont le decltype type de retour dépend des types de ses arguments de modèle. Par exemple, considérez l’exemple de code suivant dans lequel le type de retour du modèle de fonction dépend des types des arguments de modèle. Dans l’exemple de code, l’espace UNKNOWN réservé indique que le type de retour ne peut pas être spécifié.
template<typename T, typename U>
UNKNOWN func(T&& t, U&& u){ return t + u; }
L’introduction du decltype spécificateur de type permet à un développeur d’obtenir le type de l’expression retournée par le modèle de fonction. Utilisez la syntaxe de déclaration de fonction alternative affichée ultérieurement, le auto mot clé et le decltype spécificateur de type pour déclarer un type de retour spécifié tardivement . Le type de retour spécifié tardivement est déterminé lorsque la déclaration est compilée, au lieu du moment où elle est codée.
Le prototype suivant illustre la syntaxe d’une déclaration de fonction alternative. Les const qualificateurs et volatile les qualificateurs et la spécification d’exceptionthrow sont facultatifs. L’espace function_body réservé représente une instruction composée qui spécifie ce que fait la fonction. Comme meilleure pratique de codage, l’espace expression réservé dans l’instruction decltype doit correspondre à l’expression spécifiée par l’instruction return , le cas échéant, dans le function_body.
auto
function_name
(
parameters
opter)constoptervolatileopter->decltype(expression)noexceptopter{function_body};
Dans l’exemple de code suivant, le type de retour spécifié tardivement du modèle de myFunc fonction est déterminé par les types des arguments du modèle et u du t modèle. Comme meilleure pratique de codage, l’exemple de code utilise également des références rvalue et le forward modèle de fonction, qui prennent en charge le transfert parfait. Pour plus d’informations, consultez le déclarateur de référence Rvalue : &>.
//C++11
template<typename T, typename U>
auto myFunc(T&& t, U&& u) -> decltype (forward<T>(t) + forward<U>(u))
{ return forward<T>(t) + forward<U>(u); }
//C++14
template<typename T, typename U>
decltype(auto) myFunc(T&& t, U&& u)
{ return forward<T>(t) + forward<U>(u); }
decltype et les fonctions de transfert (C++11)
Le transfert de fonctions encapsule les appels vers d’autres fonctions. Considérez un modèle de fonction qui transfère ses arguments, ou les résultats d’une expression qui implique ces arguments, vers une autre fonction. En outre, la fonction de transfert retourne le résultat de l’appel de l’autre fonction. Dans ce scénario, le type de retour de la fonction de transfert doit être identique au type de retour de la fonction encapsulée.
Dans ce scénario, vous ne pouvez pas écrire une expression de type appropriée sans le spécificateur de decltype type. Le decltype spécificateur de type active les fonctions de transfert génériques, car il ne perd pas les informations requises sur la manière dont une fonction retourne un type de référence. Pour obtenir un exemple de code d’une fonction de transfert, consultez l’exemple de modèle de fonction précédent myFunc .
Exemples
L’exemple de code suivant déclare le type de retour spécifié tardivement du modèle Plus()de fonction. La Plus fonction traite ses deux opérandes avec la operator+ surcharge. Ainsi, l’interprétation de l’opérateur plus (+) et du type de retour de la Plus fonction dépend des types des arguments de fonction.
// decltype_1.cpp
// compile with: cl /EHsc decltype_1.cpp
#include <iostream>
#include <string>
#include <utility>
#include <iomanip>
using namespace std;
template<typename T1, typename T2>
auto Plus(T1&& t1, T2&& t2) ->
decltype(forward<T1>(t1) + forward<T2>(t2))
{
return forward<T1>(t1) + forward<T2>(t2);
}
class X
{
friend X operator+(const X& x1, const X& x2)
{
return X(x1.m_data + x2.m_data);
}
public:
X(int data) : m_data(data) {}
int Dump() const { return m_data;}
private:
int m_data;
};
int main()
{
// Integer
int i = 4;
cout <<
"Plus(i, 9) = " <<
Plus(i, 9) << endl;
// Floating point
float dx = 4.0;
float dy = 9.5;
cout <<
setprecision(3) <<
"Plus(dx, dy) = " <<
Plus(dx, dy) << endl;
// String
string hello = "Hello, ";
string world = "world!";
cout << Plus(hello, world) << endl;
// Custom type
X x1(20);
X x2(22);
X x3 = Plus(x1, x2);
cout <<
"x3.Dump() = " <<
x3.Dump() << endl;
}
Plus(i, 9) = 13
Plus(dx, dy) = 13.5
Hello, world!
x3.Dump() = 42
Visual Studio 2017 et versions ultérieures : Le compilateur analyse les decltype arguments lorsque les modèles sont déclarés plutôt que instanciés. Par conséquent, si une spécialisation non dépendante est trouvée dans l’argument decltype , elle ne sera pas différée au moment de l’instanciation ; elle est traitée immédiatement et toutes les erreurs résultantes sont diagnostiqués à ce moment-là.
L’exemple suivant montre une telle erreur de compilateur déclenchée au point de déclaration :
#include <utility>
template <class T, class ReturnT, class... ArgsT> class IsCallable
{
public:
struct BadType {};
template <class U>
static decltype(std::declval<T>()(std::declval<ArgsT>()...)) Test(int); //C2064. Should be declval<U>
template <class U>
static BadType Test(...);
static constexpr bool value = std::is_convertible<decltype(Test<T>(0)), ReturnT>::value;
};
constexpr bool test1 = IsCallable<int(), int>::value;
static_assert(test1, "PASS1");
constexpr bool test2 = !IsCallable<int*, int>::value;
static_assert(test2, "PASS2");
Spécifications
Visual Studio 2010 ou versions ultérieures.
decltype(auto) nécessite Visual Studio 2015 ou version ultérieure.