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
auto
Dichiaratore Inizializzatore;
[](auto
param1, 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, const
ad esempio , , volatile
puntatore (*
), 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 int
oggetto , 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 int
e 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