Parola chiave automatica C ++. Perché è magico?


144

Da tutto il materiale che ho usato per imparare il C ++, autoè sempre stato uno strano identificatore della durata della memoria che non ha avuto alcuno scopo. Ma solo di recente ho riscontrato codice che lo utilizzava come nome di tipo in sé e per sé. Per curiosità l'ho provato, e assume il tipo di qualsiasi cosa mi capiti di assegnargli!

Improvvisamente iteratori STL e, beh, tutto ciò che utilizza modelli è 10 volte più facile da scrivere. Mi sembra di usare un linguaggio "divertente" come Python.

Dove è stata questa parola chiave per tutta la mia vita? Dirigi i miei sogni dicendo che è esclusivo di Visual Studio o non portatile?


18
non è. Magia. È nuovo ( oh no, che brutto gioco di parole ). Ora async è il futuro ( sussulto )
visto il

2
Ecco il riferimento sulle parole chiave auto en.cppreference.com/w/cpp/language/auto
andyqee

Risposte:


149

auto era una parola chiave che C ++ "ereditava" da C che era stata lì quasi per sempre, ma praticamente mai usata perché c'erano solo due possibili condizioni: o non era permesso, oppure era assunto per impostazione predefinita.

L'uso di autoper indicare un tipo dedotto era nuovo con C ++ 11.

Allo stesso tempo, auto x = initializerdeduce il tipo di xdal tipo initializernello stesso modo in cui la deduzione del tipo di modello funziona per i modelli di funzione. Considera un modello di funzione come questo:

template<class T>
int whatever(T t) { 
    // point A
};

Al punto A, è stato assegnato un tipo in Tbase al valore passato per il parametro a whatever. Quando lo fai auto x = initializer;, viene utilizzata la stessa detrazione del tipo per determinare il tipo xdal tipo di initializerquello utilizzato per inizializzarlo.

Ciò significa che la maggior parte della meccanica di deduzione del tipo che un compilatore deve implementare autoera già presente e utilizzata per i modelli su qualsiasi compilatore che tentasse persino di implementare C ++ 98/03. Pertanto, l'aggiunta del supporto è autostata apparentemente abbastanza semplice essenzialmente per tutti i team di compilatori: è stato aggiunto abbastanza rapidamente e sembra che ci siano stati anche alcuni bug ad esso correlati.

Quando questa risposta era stata originariamente scritta (nel 2011, prima che l'inchiostro fosse asciutto sullo standard C ++ 11) autoera già abbastanza portatile. Oggi è completamente portatile tra tutti i compilatori tradizionali. Le uniche ovvie ragioni per evitarlo sarebbero se devi scrivere un codice compatibile con un compilatore C, o hai una necessità specifica di indirizzare un compilatore di nicchia che sai che non lo supporta (ad esempio, alcune persone scrivono ancora codice per MS-DOS utilizzando compilatori di Borland, Watcom, ecc., che non hanno visto aggiornamenti significativi da decenni). Se stai usando una versione ragionevolmente attuale di uno dei compilatori mainstream, non c'è motivo di evitarlo affatto.


23

Sta solo prendendo una parola chiave generalmente inutile e dandole una nuova funzionalità migliore. È standard in C ++ 11 e la maggior parte dei compilatori C ++ con persino un supporto C ++ 11 lo supporterà.


Oh! Ah, non ho mai pensato al linguaggio C ++ come a una cosa che potrebbe cambiare in sé e per sé. Dovrò cercare cos'altro hanno aggiunto in questo C ++ 11, ho sentito un po 'di C ++ 0x ma non ho mai scavato troppo in profondità.
Anne Quinn,

7
@Clairvoire C ++ 0x era il nome provvisorio. È stato pubblicato questo mese e quindi è diventato C ++ 11.
R. Martinho Fernandes,

13

Per le variabili, specifica che il tipo di variabile che viene dichiarato verrà automaticamente dedotto dal suo inizializzatore. Per le funzioni, specifica che il tipo restituito è un tipo di restituzione finale o che verrà dedotto dalle sue dichiarazioni di restituzione (dal C ++ 14).

Sintassi

auto variable initializer   (1) (since C++11)

auto function -> return type    (2) (since C++11)

auto function   (3) (since C++14)

decltype(auto) variable initializer (4) (since C++14)

decltype(auto) function (5) (since C++14)

auto :: (6) (concepts TS)

cv(optional) auto ref(optional) parameter   (7) (since C++14)

Spiegazione

1) Quando si dichiarano variabili nell'ambito del blocco, nell'ambito dello spazio dei nomi, nelle istruzioni di inizializzazione di per i cicli, ecc., La parola chiave auto può essere usata come identificatore del tipo. Una volta determinato il tipo di inizializzatore, il compilatore determina il tipo che sostituirà la parola chiave auto utilizzando le regole per la deduzione dell'argomento del modello da una chiamata di funzione (per ulteriori dettagli, vedere deduzione dell'argomento del modello # Altri contesti). La parola chiave auto può essere accompagnata da modificatori, come const o &, che parteciperanno alla detrazione del tipo. Ad esempio, dato const auto& i = expr;, il tipo di i è esattamente il tipo dell'argomento u in un modello immaginario template<class U> void f(const U& u)se la funzione chiamaf(expr)è stato compilato. Pertanto, auto && può essere dedotto come riferimento lvalue o riferimento rvalue secondo l'inizializzatore, che viene utilizzato in base all'intervallo per il loop. Se si utilizza auto per dichiarare più variabili, i tipi dedotti devono corrispondere. Ad esempio, la dichiarazione auto i = 0, d = 0.0;non auto i = 0, *p = &i;è corretta , mentre la dichiarazione è ben formata e l'auto viene dedotta come int.

2) In una dichiarazione di funzione che utilizza la sintassi del tipo di ritorno finale, la parola chiave auto non esegue il rilevamento automatico del tipo. Serve solo come parte della sintassi.

3) In una dichiarazione di funzione che non utilizza la sintassi del tipo di ritorno finale, la parola chiave auto indica che il tipo di ritorno verrà dedotto dall'operando della sua dichiarazione di ritorno usando le regole per la deduzione dell'argomento modello.

4) Se il tipo dichiarato della variabile è decltype (auto), la parola chiave auto viene sostituita con l'espressione (o l'elenco delle espressioni) del suo inizializzatore e il tipo effettivo viene dedotto usando le regole per decltype.

5) Se il tipo restituito della funzione è dichiarato decltype (auto), la parola chiave auto viene sostituita con l'operando della sua istruzione return e il tipo restituito effettivo viene dedotto usando le regole per decltype.

6) Un identificatore di nome nidificato del modulo auto :: è un segnaposto che viene sostituito da una classe o da un tipo di enumerazione seguendo le regole per la detrazione di segnaposto di tipo vincolato.

7) Una dichiarazione di parametro in un'espressione lambda. (dal C ++ 14) Una dichiarazione di parametro di funzione. (concetti TS)

Note Fino a C ++ 11, auto aveva la semantica di un identificatore della durata della memoria. La miscelazione di variabili e funzioni automatiche in un'unica dichiarazione, come in, auto f() -> int, i = 0;non è consentita.

Per maggiori informazioni: http://en.cppreference.com/w/cpp/language/auto


11

Questa funzionalità non è stata lì per tutta la vita. È supportato in Visual Studio dalla versione 2010. È una nuova funzionalità C ++ 11, quindi non è esclusiva di Visual Studio ed è / sarà portatile. La maggior parte dei compilatori lo supporta già.


3

Non sta andando da nessuna parte ... è una nuova funzionalità C ++ standard nell'implementazione di C ++ 11. Detto questo, mentre è uno strumento meraviglioso per semplificare le dichiarazioni di oggetti e per ripulire la sintassi di alcuni paradigmi di chiamata (ad es. Per i loop basati su range), non usarlo eccessivamente / abusare :-)


3

La parola chiave automatica specifica che il tipo di variabile che viene dichiarato verrà automaticamente detratto dal suo inizializzatore. In caso di funzioni, se il loro tipo restituito è auto, questo verrà valutato dall'espressione del tipo restituito in fase di esecuzione.

Può essere molto utile quando dobbiamo usare l'iteratore. Ad esempio, per il codice sottostante possiamo semplicemente usare "auto" invece di scrivere l'intera sintassi dell'iteratore.

int main() 
{ 

// Initialize set 
set<int> s; 

s.insert(1); 
s.insert(4); 
s.insert(2); 
s.insert(5); 
s.insert(3); 

// iterator pointing to 
// position where 2 is 
auto pos = s.find(3); 

// prints the set elements 
cout << "The set elements after 3 are: "; 
for (auto it = pos; it != s.end(); it++) 
    cout << *it << " "; 

return 0; 
}

Ecco come possiamo usare la parola chiave "auto"


0

È magico è la capacità di ridurre la necessità di scrivere codice per ogni tipo di variabile passato a funzioni specifiche. Considera una funzione print () simile a Python nella sua base C.

#include <iostream>
#include <string>
#include <array>

using namespace std;

void print(auto arg) {
     cout<<arg<<" ";
}

int main()
{
  string f = "String";//tok assigned
  int x = 998;
  double a = 4.785;
  string b = "C++ Auto !";
//In an opt-code ASCII token stream would be iterated from tok's as:
  print(a);
  print(b);
  print(x);
  print(f);
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.