Condividi tramite


auto (C++)

Deduce il tipo di una variabile dichiarata dall'espressione di inizializzazione.

Nota

Lo standard C++ definisce un significato originale e modificato per questa parola chiave. Prima di Visual Studio 2010, la auto parola chiave dichiara una variabile nella classe di archiviazione automatica , ovvero una variabile con durata locale. A partire da Visual Studio 2010, la auto parola chiave dichiara una variabile il cui tipo viene dedotto dall'espressione di inizializzazione nella relativa dichiarazione. L'opzione /Zc:auto[-] del compilatore controlla il significato della auto parola chiave .

Sintassi

autoDichiaratore Inizializzatore ;

[](autoparam1 , auto param2 ) {};

Osservazioni:

La auto parola chiave indirizza il compilatore all'uso dell'espressione di inizializzazione di una variabile dichiarata o di un parametro di espressione lambda per dedurre il relativo tipo.

È consigliabile usare la parola chiave per la auto maggior parte delle situazioni, a meno che non si desideri davvero una conversione, perché offre questi vantaggi:

  • Affidabilità: se il tipo dell'espressione viene modificato, incluso quando viene modificato un tipo restituito di funzione, funziona solo.

  • Prestazioni: si garantisce che non ci sia alcuna conversione.

  • Usabilità: non è necessario preoccuparsi delle difficoltà di ortografia del nome del tipo e degli errori di digitazione.

  • Efficienza: la codifica può essere più efficiente.

Casi di conversione in cui potrebbe non essere necessario usare auto:

  • Si vuole un tipo specifico e non verranno eseguite altre operazioni.

  • Nei tipi helper del modello di espressione, (valarray+valarray)ad esempio .

Per usare la auto parola chiave , usarla invece di un tipo per dichiarare una variabile e specificare un'espressione di inizializzazione. Inoltre, è possibile modificare la auto parola chiave usando identificatori e dichiaratori, constad esempio , , volatilepuntatore (*), riferimento (&) e riferimento rvalue (&&). Il compilatore valuta l'espressione di inizializzazione, quindi utilizza tali informazioni per dedurre il tipo della variabile.

L'espressione auto di inizializzazione può assumere diverse forme:

  • Sintassi di inizializzazione universale, ad esempio auto a { 42 };.
  • Sintassi di assegnazione, ad esempio auto b = 0;.
  • Sintassi di assegnazione universale, che combina le due forme precedenti, ad esempio auto c = { 3.14159 };.
  • Inizializzazione diretta o sintassi di tipo costruttore, ad esempio auto d( 1.41421f );.

Per altre informazioni, vedere Inizializzatori e gli esempi di codice più avanti in questo documento.

Quando auto viene usato per dichiarare il parametro di ciclo in un'istruzione basata su for intervallo, usa una sintassi di inizializzazione diversa, ad esempio for (auto& i : iterable) do_action(i);. Per altre informazioni, vedere Istruzione basata su for intervalli (C++).

La auto parola chiave è un segnaposto per un tipo, ma non è un tipo. Di conseguenza, la auto parola chiave non può essere usata in cast o operatori come sizeof e (per C++/CLI). typeid

Utilizzabilità

La auto parola chiave è un modo semplice per dichiarare una variabile con un tipo complesso. Ad esempio, è possibile usare auto per dichiarare una variabile in cui l'espressione di inizializzazione include modelli, puntatori a funzioni o puntatori ai membri.

È anche possibile usare auto per dichiarare e inizializzare una variabile in un'espressione lambda. Non è possibile dichiarare il tipo della variabile manualmente poiché il tipo di un'espressione lambda è noto solo al compilatore. Per altre informazioni, vedere Esempi di espressioni lambda.

Tipi restituiti finali

È possibile usare auto, insieme all'identificatore decltype di tipo , per scrivere librerie di modelli. Usare auto e decltype per dichiarare un modello di funzione il cui tipo restituito dipende dai tipi degli argomenti del modello. In alternativa, usare auto e decltype per dichiarare un modello di funzione che esegue il wrapping di una chiamata a un'altra funzione e quindi restituisce il tipo restituito di tale altra funzione. Per ulteriori informazioni, vedere decltype.

Riferimenti ed elementi cv-qualifier

L'uso di auto elimina riferimenti, const qualificatori e volatile qualificatori. Si consideri l'esempio seguente:

// 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;
}

Nell'esempio precedente myAuto è un intoggetto , non un int riferimento, quindi l'output è 11 11, non 11 12 come nel caso in cui il qualificatore di riferimento non fosse stato eliminato da auto.

Deduzione del tipo con inizializzatori parentesi graffe (C++14)

Nell'esempio di codice seguente viene illustrato come inizializzare una auto variabile usando parentesi graffe. Si noti la differenza tra B e C e tra A ed 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;
}

Restrizioni e messaggi di errore

Nella tabella seguente sono elencate le restrizioni sull'uso della auto parola chiave e il messaggio di errore di diagnostica corrispondente generato dal compilatore.

Numero di errore Descrizione
C3530 La auto parola chiave non può essere combinata con altri identificatori di tipo.
C3531 Un simbolo dichiarato con la auto parola chiave deve avere un inizializzatore.
C3532 La parola chiave è stata usata auto erroneamente per dichiarare un tipo. Ad esempio, è stato dichiarato un tipo restituito di un metodo o una matrice.
C3533, C3539 Non è possibile dichiarare un parametro o un argomento modello con la auto parola chiave .
C3535 Non è possibile dichiarare un metodo o un parametro di modello con la auto parola chiave .
C3536 Non è possibile usare un simbolo prima dell'inizializzazione. In pratica, significa che una variabile non può essere usata per inizializzare se stessa.
C3537 Non è possibile eseguire il cast a un tipo dichiarato con la auto parola chiave .
C3538 Tutti i simboli in un elenco dichiaratore dichiarato con la auto parola chiave devono essere risolti nello stesso tipo. Per altre informazioni, vedere Dichiarazioni e definizioni.
C3540, C3541 Gli operatori sizeof e typeid non possono essere applicati a un simbolo dichiarato con la auto parola chiave .

Esempi

Questi frammenti di codice illustrano alcuni dei modi in cui è possibile usare la auto parola chiave .

Le dichiarazioni seguenti sono equivalenti. Nella prima istruzione la variabile j viene dichiarata come di tipo int. Nella seconda istruzione, la variabile k viene dedotta come tipo int perché l'espressione di inizializzazione (0) è un numero intero.

int j = 0;  // Variable j is explicitly type int.
auto k = 0; // Variable k is implicitly type int because 0 is an integer.

Le dichiarazioni seguenti sono equivalenti, ma la seconda dichiarazione è più semplice della prima. Uno dei motivi più interessanti per usare la auto parola chiave è semplicità.

map<int,list<string>>::iterator i = m.begin();
auto i = m.begin();

Il frammento di codice seguente dichiara il tipo di variabili iter e elem all'avvio dei for cicli di intervallo for e .

// 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
    { /* ... */ }
}

Il frammento di codice seguente usa l'operatore e la new dichiarazione del puntatore per dichiarare i puntatori.

double x = 12.34;
auto *y = new auto(x), **z = new auto(&x);

Il frammento di codice seguente dichiara più simboli in ogni istruzione di dichiarazione. Si noti che tutti i simboli in ogni istruzione vengono risolte nello stesso tipo.

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.

Questo frammento di codice usa l'operatore condizionale (?:) per dichiarare la variabile x come intero con un valore di 200:

int v1 = 100, v2 = 200;
auto x = v1 > v2 ? v1 : v2;

Il frammento di codice seguente inizializza la variabile x in modo da digitare int, variabile y a un riferimento al tipo const inte variabile a un puntatore a una funzione che restituisce fp il tipo 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;
    //...
}

Vedi anche

Parole chiave
/Zc:auto (Dedurre il tipo di variabile)
sizeof operatore
typeid
operator new
Dichiarazioni e definizioni
Esempi di espressioni lambda
Inizializzatori
decltype