auto, mot clé (déduction de type)
Déduit le type d'une variable déclarée de l'expression d'initialisation.
auto declarator initializer;
Notes
Le mot clé auto conduit le compilateur à utiliser l'expression d'initialisation d'une variable déclarée pour déduire son type.
Nous vous recommandons d'utiliser le mot clé auto pour la plupart des situations- sauf si vous souhaitez réellement une conversion- car il fournit ces avantages :
Robustesse : si le type de l'expression est modifié - cela inclut le cas où un type de retour de fonction est modifié- tout fonctionne.
Performance: vous êtes certain qu'il n'y aura aucune conversion.
Usage: vous n'avez pas à vous préoccuper des difficultés et des typos d'orthographe du nom de type.
Efficacité : Votre codage peut être plus efficace.
Cas de conversion dans lesquels vous ne pouvez pas utiliser auto:
Lorsque vous souhaitez un type spécifique et rien d'autre n'irait.
Types de programmes d'assistance basé sur un modèle d'expression- par exemple, (valarray+valarray) et les lists d'initialiseurs, bien que vous choisirez rarement d'écrire auto x = { 1 }; et compter vraiment obtenir int.
Pour utiliser le mot clé auto, utilisez-le au lieu d'un type pour déclarer une variable, puis spécifiez une expression d'initialisation. En outre, vous pouvez modifier le mot clé auto en utilisant des spécificateurs et des déclarateurs tels que const, volatile, le pointeur (*), la référence (&), et la référence rvalue (&&). Le compilateur évalue l'expression d'initialisation puis utilise ces informations pour déduire le type de variable.
L'expression d'initialisation peut être une assignation (syntaxe de signe égal), une initialisation directe (syntaxe de style fonction), une expression operator new, ou l'expression d'initialisation peut être le paramètre de for-range-declaration dans une instruction Basé sur une plage, instruction (C++). Pour plus d'informations, consultez Initialiseurs et les exemples de codes de ce document.
Le mot clé auto est un espace réservé pour un type, mais ce n'est pas lui-même un type. Par conséquent, le mot clé auto ne peut pas être utilisé dans les casts ou sur les opérateurs tels que sizeof et typeid.
Utilité
Le mot clé auto est un moyen simple de déclarer une variable possédant un type complexe. Par exemple, vous pouvez utiliser auto pour déclarer une variable où l'expression d'initialisation implique des modèles, les pointeurs fonction, ou les pointeurs vers des membres.
Vous pouvez également utiliser auto pour déclarer et initialiser une variable à 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 aider à écrire des bibliothèques de modèles. Par exemple, utilisez auto and decltype pour déclarer une fonction modèle dont le type de retour dépend des types de ses modèles d'arguments. Sinon, utilisez auto et decltype pour déclarer une fonction modèle qui encapsule un appel à une autre fonction, et renvoie alors quel que soit le type du résultat de cette autre fonction. Pour plus d'informations, consultez Spécificateur de type decltype.
Références et cv-qualificateurs
Notez que l'utilisation de références de déplacements de auto, les qualificateurs const, et les qualificateurs volatiles. 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;
}
Vous pouvez croyez que le myAuto est une référence d'entier, mais ce n'est pas le cas. C'est simplement un entier, donc la sortie est 11 11, pas 11 12 comme cela aurait été le cas si la référence n'avait pas été supprimée par auto.
Messages d'erreur et restrictions
Le tableau suivant répertorie les restrictions sur l'utilisation du mot clé auto, et le message d'erreur de diagnostic correspondant émit par le compilateur.
Numéro de l'erreur |
Description |
---|---|
Le mot-clef auto ne peut pas être combiné avec un autre spécificateur de type. |
|
Un symbole qui est déclaré avec le mot clé auto doit avoir un initialiseur. |
|
Vous avez utilisé incorrectement le mot clé auto pour déclarer un type. Par exemple, vous avez défini un type de retour de méthode ou un tableau. |
|
Un paramètre ou un modèle d'argument ne peut pas être déclaré avec le mot clé auto. |
|
Un symbole qui est déclaré avec le mot clé auto dans une expression new doit avoir un initialiseur. Pour plus d'informations, consultez new, opérateur (<new>). |
|
Un paramètre ou un modèle d'argument ne peut pas être déclaré avec le mot clé auto. |
|
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. |
|
Vous ne pouvez pas convertir en un type qui est déclaré avec le mot clé auto. |
|
Tous les symboles dans une liste de déclarateurs qui sont déclarés avec le mot clé auto doit le résoudre au même type. Pour plus d'informations, consultez Déclarations. |
|
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 quelques-unes des utilisations où le mot clé auto peut être utilisé.
Les déclarations suivantes sont équivalentes. Dans la première instruction, la variable j est déclarée comme type int. Dans la deuxième instruction, la variable k est déduite d'être 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 deuxième déclaration est plus simple que la première. Une des raisons incontestables 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 de variables iter et elem lorsque le début de boucles for et for de la plage.
// 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'operateur et déclarateur de pointeur new 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 les symboles dans chaque instruction se résolvent au 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 comme entier qui a la valeur 200 :
int v1 = 100, v2 = 200;
auto x = v1 > v2 ? v1 : v2;
Le fragment de code suivant initialise la variable x au type int, la variable y à une référence au type const, intet fp variable à 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
Référence
Spécificateurs de classe de stockage