Lo specificatore auto
ha subito una vera e propria trasformazione durante l'evoluzione dello standard storage di default per le variabili allocate a stack, è stato poco impiegato per via della sua scarsa utilità pratica. Tuttavia, a partire dall'introduzione dello standard C++11 esso ha assunto una valenza semantica completamente differente, che lo ha giustamente reso una delle caratteristiche più popolari del linguaggio.
Usato nella dichiarazione di una variabile, auto
consente infatti di delegare al potente meccanismo di inferenza del compilatore la definizione del tipo.</">C++.
Inizialmente designato come specificatore di storage di default per le variabili allocate a stack, è stato poco impiegato per via della sua scarsa utilità pratica. Tuttavia, a partire dall'introduzione dello standard C++11 esso ha assunto una valenza semantica completamente differente, che lo ha giustamente reso una delle caratteristiche più popolari del linguaggio.
Usato nella dichiarazione di una variabile, auto
consente infatti di delegare al potente meccanismo di inferenza del compilatore la definizione del tipo.
Ad esempio, nel frammento seguente, il compilatore è in grado di inferire che il tipo della variabile x è double
basandosi sulla valutazione dell'espressione usata per la sua inizializzazione.
#include <iostream>
#include <cmath>
#include <typeinfo>
int main()
{
auto x = 34.0f - sqrt('a' / 3.0);
// Stamperà a schermo 'd' o 'double'
std::cout << "The type of x is " << typeid(x).name() << "\n";
return 0;
}
Si osservi che l'uso di auto
non costituisce una deroga alle regole imposte dalla tipizzazione forte del linguaggio, poiché la determinazione del tipo avviene a tempo di compilazione.
Ciò significa che, una volta desunto il tipo appropriato, il compilatore userà questa informazione per valutare la correttezza formale dell'uso di tale variabile nel suo contesto di definizione, alla stregua di una variabile definita in modo tradizionale.
Ad esempio, modificando il listato precedente come segue, otterremo un errore di compilazione dovuto all'uso improprio di una variabile di tipo double
come argomento dell'operatore di modulo %
.
#include <cmath>
int main()
{
auto x = 34.0f - sqrt('a' / 3.0);
// Errore: gli operandi di '%' devono essere valori interi!
int b = x % 2;
return 0;
}
In questa modalità d'impiego, auto
è inoltre compatibile con i qualificatori del linguaggio che concorrono alla definizione del tipo di un'istanza come const ed il modificatore & per indicare un riferimento a variabile.
La moderna caratterizzazione dello specificatore auto
, a partire dall'introduzione di C++ 11, lo rende quindi un ausilio alla codifica non strettamente necessario, ma estremamente comodo in alcuni scenari d'uso.
Ad esempio, esso si rivela particolarmente utile quando è associato all'uso di costrutti template poiché consente di semplificare il compito del programmatore.
In quest'ottica, si consideri il caso molto frequente della dichiarazione di iteratori che può facilmente degenerare in un'istruzione prolissa e poco leggibile. Nel frammento seguente, auto
viene usato per dichiarare la variabile iteratore usata per la scansione di un container nel contesto di un costrutto iterativo:
#include <iostream>
int main()
{
std::list<int> l = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
for (auto it = l.begin(); it != l.end(); ++it)
{
std::cout << *it << ' ';
}
return 0;
}
L'uso di auto
, in questo caso, non solo snellisce la definizione del ciclo, ma apporta anche un considerevole vantaggio in termini di manutenibilità. Supponendo infatti di dover revisionare il codice, ad esempio per cambiare il tipo del dato gestito dal container da int
a double
, non sarà necessario correggere la definizione della variabile it per adeguarla al nuovo requisito.
L'uso dello specificatore auto
infatti ci esonera dal tedioso compito di aggiornare il codice, demandando al compilatore l'inferenza del tipo corretto in osservanza dei principi di concordanza del linguaggio.
Altri usi e controindicazioni di auto
Le revisioni successive dello standard hanno ampliato ulteriormente la valenza semantica di auto
. In particolare, nelle ultime versioni dello standard esso è usabile al posto del tipo di ritorno di una funzione o dei suoi parametri, nonché come argomento nella definizione di template.
L'estensione delle modalità d'uso di auto chiaramente cerca di rispondere alla necessità di mitigare la prolissità del linguaggio C++, preservando i meccanismi di controllo della compatibilità dei tipi, che sono fondamentali per il suo funzionamento.
Tuttavia, un uso improprio o eccessivo può potenzialmente minare questa finalità, producendo invece l'effetto contrario.
Va ricordato che, come molte delle funzionalità più evolute del linguaggio, auto
non è un costrutto essenziale, nel senso che esso non ha alcun peso sulla capacità espressiva di base del linguaggio. Il suo uso dovrebbe essere quindi subordinato ad un'attenta valutazione e limitato a porzioni di codice facilmente intellegibili anche senza indicazione esplicita dei tipi in uso.