Notes
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.
Déduit le type d'une variable déclarée de son expression d'initialisation.
Remarque
La norme C++ définit une signification originale et modifiée de ce mot clé. Avant Visual Studio 2010, le mot clé auto
déclare une variable dans la classe de stockage automatique ; c'est-à-dire, une variable qui a une durée de vie locale. À partir de Visual Studio 2010, le mot clé auto
déclare une variable dont le type est déduit de l’expression d’initialisation de la déclaration. L'option du compilateur /Zc:auto[-]
contrôle la signification du mot clé auto
.
Syntaxe
auto
declarator initializer;
[](auto
param1, auto
param2) {};
Notes
Le mot clé auto
indique au compilateur d’utiliser l’expression d’initialisation d’une variable déclarée, ou d’un paramètre d’expression lambda, pour déduire son type.
Nous vous recommandons d’utiliser le mot clé auto
dans la plupart des cas, sauf si vous voulez vraiment une conversion, en raison des avantages suivants :
Robustesse : Si le type de l’expression est modifié, notamment quand un type de retour de fonction est modifié, cela fonctionne.
Performances : Vous avez la garantie qu’il n’y a aucune conversion.
Utilisabilité : Vous n’avez pas à vous soucier des fautes de frappe ni des problèmes liés à l’orthographe de nom de type.
Efficacité : Votre codage peut être plus efficace.
Cas de conversion où il est déconseillé d'utiliser auto
:
Quand vous souhaitez un type spécifique et que rien d’autre ne convient.
Dans les types d’assistance de modèle d’expression, par exemple
(valarray+valarray)
.
Pour utiliser le mot clé auto
, utilisez-le plutôt à la place d’un type pour déclarer une variable et spécifiez une expression d’initialisation. De plus, vous pouvez modifier le mot clé auto
en utilisant des spécificateurs et des déclarateurs comme const
, volatile
, un pointeur (*
), une référence (&
) et une référence rvalue (&&
). Le compilateur évalue l'expression d'initialisation et utilise ensuite ces informations pour déduire le type de la variable.
L’expression d’initialisation auto
peut prendre plusieurs formes :
- Syntaxe d’initialisation universelle, telle que
auto a { 42 };
. - Syntaxe d’assignation, telle que
auto b = 0;
. - Syntaxe d’assignation universelle, qui combine les deux formes précédentes, telle que
auto c = { 3.14159 };
. - Initialisation directe ou syntaxe de style constructeur, telle que
auto d( 1.41421f );
.
Pour plus d’informations, consultez Initialiseurs et les exemples de code plus loin dans ce document.
Lorsque auto
est utilisé pour déclarer le paramètre de boucle dans une instruction for
basée sur une plage, il utilise une syntaxe d’initialisation différente, par exemple for (auto& i : iterable) do_action(i);
. Pour plus d’informations, consultez Instruction for
basée sur une plage (C++).
Le mot clé auto
est un espace réservé pour un type, mais il n'est pas lui-même un type. C’est pourquoi le mot clé auto
ne peut pas être utilisé dans des casts ni des opérateurs tels que sizeof
et (pour C++/CLI) typeid
.
Utilité
Le mot clé auto
est un moyen simple de déclarer une variable qui a un type complexe. Par exemple, vous pouvez utiliser auto
pour déclarer une variable où l’expression d’initialisation implique des modèles, des pointeurs vers des fonctions ou des pointeurs vers des membres.
Vous pouvez également utiliser auto
pour déclarer et initialiser une variable sur une expression lambda. Vous ne pouvez pas déclarer le type de la variable vous-même, car le type d’une expression lambda est connu uniquement du compilateur. Pour plus d’informations, consultez Exemples d’expressions lambda.
Types de retour de fin
Vous pouvez utiliser auto
, avec le spécificateur de type decltype
, pour écrire des bibliothèques de modèles. Utilisez auto
et decltype
pour déclarer un modèle de fonction dont le type de retour dépend des types de ses arguments de modèle. Sinon, utilisez auto
et decltype
pour déclarer un modèle de fonction qui enveloppe un appel dans une autre fonction, puis retourne le type de retour de cette autre fonction, quel qu’il soit. Pour plus d’informations, consultez decltype
.
Références et qualificateurs cv
L’utilisation du mot clé auto
supprime les références, les qualificateurs const
et les qualificateurs volatile
. Prenons l’exemple suivant :
// cl.exe /analyze /EHsc /W4
#include <iostream>
using namespace std;
int main( )
{
int count = 10;
int& countRef = count;
auto myAuto = countRef;
countRef = 11;
cout << count << " ";
myAuto = 12;
cout << count << endl;
}
Dans l’exemple précédent, myAuto est un int
, et non une référence int
, de sorte que la sortie est 11 11
, et non 11 12
, comme ce serait le cas si le qualificateur de référence n’avait pas été supprimé par auto
.
Déduction de type avec des initialiseurs entre accolades (C++14)
L’exemple de code suivant montre comment initialiser une variable auto
à l’aide d’accolades. Notez la différence entre B et C et entre A et E.
#include <initializer_list>
int main()
{
// std::initializer_list<int>
auto A = { 1, 2 };
// std::initializer_list<int>
auto B = { 3 };
// int
auto C{ 4 };
// C3535: cannot deduce type for 'auto' from initializer list'
auto D = { 5, 6.7 };
// C3518 in a direct-list-initialization context the type for 'auto'
// can only be deduced from a single initializer expression
auto E{ 8, 9 };
return 0;
}
Restrictions et messages d’erreur
Le tableau suivant liste les restrictions sur l'utilisation du mot clé auto
et le message d’erreur de diagnostic correspondant émis par le compilateur.
Numéro d'erreur | Description |
---|---|
C3530 | Impossible d'associer le mot clé auto à un autre spécificateur de type. |
C3531 | Un symbole qui est déclaré avec le mot clé auto doit avoir un initialiseur. |
C3532 | Vous avez utilisé le mot clé auto de façon incorrecte pour déclarer un type. Par exemple, vous avez déclaré un type de retour de méthode ou un tableau. |
C3533, C3539 | Un paramètre ou un argument de modèle ne peut pas être déclaré avec le mot clé auto . |
C3535 | Une méthode ou un paramètre de modèle ne peut pas être déclaré avec le mot clé auto . |
C3536 | Un symbole ne peut pas être utilisé avant d’être initialisé. Dans la pratique, cela signifie qu’une variable ne peut pas être utilisée pour s'initialiser. |
C3537 | Vous ne pouvez pas effectuer un cast en un type qui est déclaré avec le mot clé auto . |
C3538 | Tous les symboles dans une liste de déclarateurs qui est déclarée avec le mot clé auto doivent être résolus en un même type. Pour plus d’informations, consultez Déclarations et définitions. |
C3540, C3541 | Les opérateurs sizeof et typeid ne peuvent pas être appliqués à un symbole qui est déclaré avec le mot clé auto . |
Exemples
Ces fragments de code illustrent certaines des façons d’utiliser le mot clé auto
.
Les déclarations suivantes sont équivalentes. Dans la première instruction, la variable j
est déclarée comme étant de type int
. Dans la deuxième instruction, la variable k
est déduite comme étant de type int
, car l’expression d’initialisation (0) est un entier.
int j = 0; // Variable j is explicitly type int.
auto k = 0; // Variable k is implicitly type int because 0 is an integer.
Les déclarations suivantes sont équivalentes, mais la seconde déclaration est plus simple que la première. L’une des raisons les plus convaincantes d’utiliser le mot clé auto
est sa simplicité.
map<int,list<string>>::iterator i = m.begin();
auto i = m.begin();
Le fragment de code suivant déclare le type des variables iter
et elem
quand les boucles for
et range-for
démarrent.
// cl /EHsc /nologo /W4
#include <deque>
using namespace std;
int main()
{
deque<double> dqDoubleData(10, 0.1);
for (auto iter = dqDoubleData.begin(); iter != dqDoubleData.end(); ++iter)
{ /* ... */ }
// prefer range-for loops with the following information in mind
// (this applies to any range-for with auto, not just deque)
for (auto elem : dqDoubleData) // COPIES elements, not much better than the previous examples
{ /* ... */ }
for (auto& elem : dqDoubleData) // observes and/or modifies elements IN-PLACE
{ /* ... */ }
for (const auto& elem : dqDoubleData) // observes elements IN-PLACE
{ /* ... */ }
}
Le fragment de code suivant utilise l’opérateur new
et la déclaration de pointeur pour déclarer des pointeurs.
double x = 12.34;
auto *y = new auto(x), **z = new auto(&x);
Le fragment de code suivant déclare plusieurs symboles dans chaque instruction de déclaration. Notez que tous les symboles dans chaque instruction sont résolus en un même type.
auto x = 1, *y = &x, **z = &y; // Resolves to int.
auto a(2.01), *b (&a); // Resolves to double.
auto c = 'a', *d(&c); // Resolves to char.
auto m = 1, &n = m; // Resolves to int.
Ce fragment de code utilise l'opérateur conditionnel (?:
) pour déclarer la variable x
en tant qu'entier avec la valeur 200 :
int v1 = 100, v2 = 200;
auto x = v1 > v2 ? v1 : v2;
Le fragment de code suivant initialise la variable x
sur le type int
, la variable y
sur une référence au type const int
et la variable fp
sur un pointeur vers une fonction qui retourne le type int
.
int f(int x) { return x; }
int main()
{
auto x = f(0);
const auto& y = f(1);
int (*p)(int x);
p = f;
auto fp = p;
//...
}
Voir aussi
Mots clés
/Zc:auto
(déduire le type de variable)
sizeof
, opérateur
typeid
operator new
Déclarations et définitions
Exemples d’expressions lambda
Initialiseurs
decltype