auto – klíčové slovo (odvození typu)
Odvozuje typ deklarované proměnné z inicializačního výrazu.
auto declarator initializer;
Poznámky
Klíčové slovo auto nařizuje kompilátoru zjistit typ pomocí inicializačního výrazu deklarované proměnné.
Doporučujeme použít klíčové slovo auto pro většinu situací – pokud opravdu není vyžadován převod, protože poskytuje tyto výhody:
Odolnost: Pokud se změní typ výrazu – to zahrnuje změnu návratového typu funkce – tak to funguje.
Výkon: Je zaručeno, že se nebudou vyskytovat převody.
Použitelnost: Není nutné se obávat těžkostí při psaní názvů typů a překlepů.
Efektivnost: Kódování může být efektivnější.
Případy převodů, ve kterých není vhodné používat auto:
Pokud je vyžadován určitý typ a nic jiného.
Podpůrné typy šablony výrazů – například (valarray+valarray) a inicializační seznamy – přestože zřídka, rozhodli byste se napsat auto x = { 1 }; a ve skutečnosti očekávat int.
Při použití klíčového slova auto je nutné jej použít místo typu pro deklaraci proměnné a určit inicializační výraz.Navíc je možné změnit klíčové slovo auto pomocí specifikátorů a deklarátorů jako například const, volatile, ukazatele (*), odkazu (&) a odkazu rvalue (&&).Kompilátor vyhodnotí inicializační výraz a potom použije tyto informace pro odvození typu proměnné.
Inicializační výraz může být přiřazení (symbol rovná se), přímá inicializace (syntaxe funkce), výraz operátoru new nebo inicializační výraz může být parametr for-range-declaration ve výrazu Příkaz For založený na rozsahu (C++).Další informace naleznete v tématu Inicializátory a příklady kódu dále v tomto dokumentu.
Klíčové slovo auto je zástupný symbol pro typ, ale samo o sobě není typ.Proto klíčové slovo auto nelze použít v přetypování nebo operátorech jako například sizeof a typeid (rozšíření komponent C++).
Užitečnost
Klíčové slovo auto je jednoduchý způsob, jak deklarovat proměnnou, která má složitý typ.Například je možné použít auto pro deklarování proměnné, kde inicializační výraz zahrnuje šablony, ukazatele na funkce nebo odkazy na členy.
Je možné také použít auto pro deklaraci a inicializaci proměnné na lambda výraz.Není možné deklarovat typ proměnné ručně, protože typ lambda výrazu je znám pouze kompilátoru.Další informace naleznete v tématu Příklady výrazů lambda.
Koncové návratové typy
Je možné použít auto společně se specifikátorem typu decltype při psaní šablon knihoven.Je možné použít auto a decltype k deklarování šablony funkce, jejichž návratový typ závisí na typech argumentů šablony.Nebo je možné použít auto a decltype k deklarování šablony funkce, která zaobaluje volání další funkce a poté vrátí vše, co je návratový typ volané funkce.Další informace naleznete v tématu decltype – specifikátor typu.
Reference a kvalifikátory cv
Je nutné poznamenat, že použití auto nedovoluje použít odkazy, const kvalifikátory a volatile kvalifikátory.Příklad:
// 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;
}
Může se zdát, že myAuto je reference na int, ale není.Je to jednoduše int, takže výstup je 11 11, nikoli 11 12, jak by to bylo v případě, že by reference byla dovolena klíčovým slovem auto.
Omezení a chybové zprávy
Následující tabulka obsahuje omezení pro použití klíčového slova auto a odpovídající diagnostické chybové zprávy, které vypouští kompilátor.
Číslo chyby |
Description |
---|---|
Klíčové slovo auto nelze kombinovat s jakýmkoli jiným specifikátorem typu. |
|
Symbol, který je deklarován s klíčovým slovem auto, musí mít inicializátor. |
|
Klíčové slovo auto bylo nesprávně použito pro deklaraci typu.Například byl deklarován návratový typ metody nebo pole. |
|
Parametr nebo argument šablony nelze deklarovat klíčovým slovem auto. |
|
Symbol, který je deklarován s klíčovým slovem auto ve výrazu new, musí mít inicializátor.Další informace naleznete v tématu new – operátor (<new>). |
|
Metodu nebo parametr šablony nelze deklarovat klíčovým slovem auto. |
|
Symbol nelze použít dříve, než je inicializován.V praxi to znamená, že proměnná nemůže být použita pro inicializaci sebe sama. |
|
Nelze přetypovat na typ, který je deklarován s klíčovým slovem auto. |
|
Všechny symboly v seznamu deklarátoru, který je deklarován s klíčovým slovem auto, musí odpovídat stejnému typu.Další informace naleznete v tématu Deklarace. |
|
Operátory sizeof a typeid (rozšíření komponent C++) nelze použít se symboly, které byly deklarovány s klíčovým slovem auto. |
Příklady
Tyto fragmenty kódu ilustrují způsoby, ve kterém může být klíčové slovo auto použito.
Následující deklarace jsou ekvivalentní.V prvním příkazu je proměnná j deklarována jako typ int.Ve druhém příkazu je proměnná k odvozena na typ int, protože inicializační výraz (0) je celé číslo.
int j = 0; // Variable j is explicitly type int.
auto k = 0; // Variable k is implicitly type int because 0 is an integer.
Následující deklarace jsou ekvivalentní, ale druhá deklarace je jednodušší než první.Jedním z nejvíce přesvědčivých důvodů pro použití klíčového slova auto je jednoduchost.
map<int,list<string>>::iterator i = m.begin();
auto i = m.begin();
Následující fragment kódu deklaruje typ proměnné iter a elem při startu cyklů for a range 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
{ /* ... */ }
}
Následující fragment kódu používá operátor new a deklaraci ukazatelem pro deklaraci ukazatelů.
double x = 12.34;
auto *y = new auto(x), **z = new auto(&x);
Následující fragment kódu deklaruje více symbolů v každém příkazu deklarace.Je nutné poznamenat, že všechny symboly v každém příkazu jsou přeloženy na stejný typ.
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.
Tento fragment kódu používá podmiňovací operátor (?:) pro deklarování proměnné x jako celé číslo s hodnotou 200:
int v1 = 100, v2 = 200;
auto x = v1 > v2 ? v1 : v2;
Následující fragment kódu inicializuje proměnnou x na typ int, proměnnou y na odkaz na typ constint a proměnnou fp na ukazatel na funkci, která vrací typ 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;
//...
}
Viz také
Referenční dokumentace
/Zc:auto (odvození typu proměnné)