auto (C++)

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 révisée pour cette mot clé. Avant Visual Studio 2010, le auto mot clé déclare une variable dans la classe de stockage automatique ; autrement dit, une variable qui a une durée de vie locale. À compter de Visual Studio 2010, le mot clé déclare une variable dont le auto type est déduit de l’expression d’initialisation dans sa déclaration. L’option /Zc:auto[-] du compilateur contrôle la signification de la auto mot clé.

Syntaxe

autodeclaratorinitializer;

[](autoparam1, autoparam2) {};

Notes

L’mot clé auto dirige le compilateur à 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 auto mot clé pour la plupart des situations, sauf si vous souhaitez vraiment une conversion, car elle offre ces avantages :

  • Robustesse : si le type de l’expression est modifié, y compris lorsqu’un type de retour de fonction est modifié, il fonctionne simplement.

  • Performances : vous êtes garanti qu’il n’y a pas de conversion.

  • Facilité d’utilisation : vous n’avez pas à vous soucier des difficultés d’orthographe de nom de type et des fautes de frappe.

  • Efficacité : votre codage peut être plus efficace.

Cas de conversion dans lesquels vous ne souhaiterez peut-être pas utiliser auto:

  • Vous voulez un type spécifique et rien d’autre ne le fera.

  • Dans les types d’assistance de modèle d’expression, par exemple (valarray+valarray).

Pour utiliser le mot clé, utilisez-le auto au lieu d’un type pour déclarer une variable et spécifiez une expression d’initialisation. En outre, vous pouvez modifier la mot clé à l’aide auto de spécificateurs et de déclarateurs tels que const, , pointeur volatile(*), référence (&) et 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 auto d’initialisation peut prendre plusieurs formes :

  • Syntaxe d’initialisation universelle, telle que auto a { 42 };.
  • Syntaxe d’affectation, telle que auto b = 0;.
  • Syntaxe d’affectation universelle, qui combine les deux formes précédentes, telles 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 exemples de code plus loin dans ce document.

Lorsqu’il auto est utilisé pour déclarer le paramètre de boucle dans une instruction basée sur for une plage, il utilise une syntaxe d’initialisation différente, par exemple for (auto& i : iterable) do_action(i);. Pour plus d’informations, consultez l’instruction basée sur for la plage (C++).

Le auto mot clé est un espace réservé pour un type, mais il n’est pas lui-même un type. Par conséquent, le auto mot clé ne peut pas être utilisé dans des casts ou des opérateurs tels que sizeof et (pour C++/CLI). typeid

Utilité

Le auto mot clé est un moyen simple de déclarer une variable qui a un type compliqué. 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 dans 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 decltype type, pour vous aider à écrire 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 cette autre fonction. Pour plus d’informations, consultez decltype.

Références et qualificateurs cv

Utilisation de auto références, const de qualificateurs et volatile de qualificateurs. 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 n’est pas une intint référence. Par conséquent, la sortie n’est 11 11pas 11 12 comme si le qualificateur de référence n’avait pas été supprimé.auto

Déduction de type avec initialiseurs accoladés (C++14)

L’exemple de code suivant montre comment initialiser une variable à l’aide d’accolades auto . 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 répertorie les restrictions relatives à l’utilisation de l’mot clé auto , ainsi que le message d’erreur de diagnostic correspondant émis par le compilateur.

Numéro d'erreur Description
C3530 La auto mot clé ne peut pas être combinée avec un autre spécificateur de type.
C3531 Un symbole déclaré avec le auto mot clé doit avoir un initialiseur.
C3532 Vous avez utilisé incorrectement la auto mot clé 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 la auto mot clé.
C3535 Une méthode ou un paramètre de modèle ne peut pas être déclaré avec la auto mot clé.
C3536 Un symbole ne peut pas être utilisé avant son initialisation. Dans la pratique, cela signifie qu’une variable ne peut pas être utilisée pour initialiser elle-même.
C3537 Vous ne pouvez pas convertir en type déclaré avec la auto mot clé.
C3538 Tous les symboles d’une liste de déclarateurs déclarées avec le auto mot clé doivent être résolus en 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 déclaré avec le auto mot clé.

Exemples

Ces fragments de code illustrent certaines des façons dont les auto mot clé peuvent être utilisées.

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 comme int type, 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 attrayantes d’utiliser le auto mot clé est la 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 le début des boucles et des for boucles de plage for .

// 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 et la new 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 en type int, la variable y vers une référence au type const intet la variable fp vers 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 (Type de variable déduiseur)
sizeof, opérateur
typeid
operator new
Déclarations et définitions
Exemples d’expressions lambda
Initialiseurs
decltype