auto (C++)

Określa typ zadeklarowanej zmiennej z wyrażenia inicjalizacji.

Uwaga

Standard języka C++ definiuje oryginalne i poprawione znaczenie dla tego słowa kluczowego. Przed programem Visual Studio 2010 auto słowo kluczowe deklaruje zmienną w klasie automatycznego magazynu, czyli zmienną o lokalnym okresie istnienia. Począwszy od programu Visual Studio 2010, słowo kluczowe deklaruje zmienną, auto której typ jest wywoływany z wyrażenia inicjalizacji w jego deklaracji. Opcja /Zc:auto[-] kompilatora kontroluje znaczenie słowa kluczowego auto .

Składnia

autoinicjator deklaratora;

[](autoparam1, autoparam2) {};

Uwagi

Słowo auto kluczowe przekierowuje kompilator do użycia wyrażenia inicjowania zadeklarowanej zmiennej lub parametru wyrażenia lambda w celu wyłudzenia jego typu.

Zalecamy używanie słowa kluczowego auto w większości sytuacji — chyba że naprawdę chcesz konwersji — ponieważ zapewnia następujące korzyści:

  • Niezawodność: jeśli typ wyrażenia zostanie zmieniony — w tym po zmianie typu zwracanego przez funkcję — po prostu działa.

  • Wydajność: masz gwarancję, że nie ma konwersji.

  • Użyteczność: nie musisz martwić się o trudności z pisownią nazw typów i literówek.

  • Wydajność: Kodowanie może być bardziej wydajne.

Przypadki konwersji, w których możesz nie chcieć użyć polecenia auto:

  • Potrzebujesz określonego typu i nic innego nie zrobi.

  • W typach pomocnika szablonu wyrażeń — na przykład (valarray+valarray).

Aby użyć auto słowa kluczowego, użyj go zamiast typu, aby zadeklarować zmienną i określić wyrażenie inicjalizacji. Ponadto można zmodyfikować auto słowo kluczowe przy użyciu specyfikatorów i deklaratorów, takich jak const, volatile, wskaźnik (), odwołanie (*&) i odwołanie rvalue (&&). Kompilator oblicza wyrażenie inicjowania, a następnie używa tych informacji do obliczenia typu zmiennej.

Wyrażenie inicjowania auto może mieć kilka form:

  • Uniwersalna składnia inicjowania, taka jak auto a { 42 };.
  • Składnia przypisania, taka jak auto b = 0;.
  • Składnia przypisania uniwersalnego, która łączy dwa poprzednie formularze, takie jak auto c = { 3.14159 };.
  • Inicjowanie bezpośrednie lub składnia w stylu konstruktora, takie jak auto d( 1.41421f );.

Aby uzyskać więcej informacji, zobacz Initializers (Inicjatory ) i przykłady kodu w dalszej części tego dokumentu.

Gdy auto jest używany do deklarowania parametru pętli w instrukcji opartej na for zakresie, używa innej składni inicjowania, na przykład for (auto& i : iterable) do_action(i);. Aby uzyskać więcej informacji, zobacz Instrukcja oparta na for zakresie (C++).

Słowo auto kluczowe jest symbolem zastępczym typu, ale nie jest typem. auto W związku z tym słowo kluczowe nie może być używane w rzutach ani operatorach, takich jak sizeof i (dla języka C++/CLI). typeid

Przydatność

Słowo auto kluczowe to prosty sposób deklarowania zmiennej, która ma skomplikowany typ. Można na przykład użyć auto metody , aby zadeklarować zmienną, w której wyrażenie inicjowania obejmuje szablony, wskaźniki do funkcji lub wskaźniki do elementów członkowskich.

Można również użyć auto polecenia , aby zadeklarować i zainicjować zmienną w wyrażeniu lambda. Nie można zadeklarować typu zmiennej samodzielnie, ponieważ typ wyrażenia lambda jest znany tylko kompilatorowi. Aby uzyskać więcej informacji, zobacz Przykłady wyrażeń lambda.

Końcowe typy zwracane

Można użyć , autowraz ze specyfikatorem decltype typu, aby ułatwić pisanie bibliotek szablonów. Użyj auto funkcji i decltype , aby zadeklarować szablon funkcji, którego typ zwracany zależy od typów argumentów szablonu. Możesz też użyć polecenia auto i decltype zadeklarować szablon funkcji, który opakowuje wywołanie innej funkcji, a następnie zwraca dowolny typ zwracany przez inną funkcję. W celu uzyskania więcej informacji, zobacz następujący temat: decltype.

Odwołania i kwalifikatory cv

Używanie auto odwołań spadkowych, const kwalifikatorów i volatile kwalifikatorów. Rozważmy następujący przykład:

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

W poprzednim przykładzie element myAuto jest odwołaniemintint, więc dane wyjściowe to 11 11, a nie 11 12 tak, gdyby kwalifikator odwołania nie został porzucony przez autoelement .

Potrącenie typu przy użyciu inicjatorów nawiasów klamrowych (C++14)

Poniższy przykład kodu pokazuje, jak zainicjować zmienną auto przy użyciu nawiasów klamrowych. Zwróć uwagę na różnicę między B i C a między A i 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;
}

Ograniczenia i komunikaty o błędach

W poniższej tabeli wymieniono ograniczenia dotyczące używania słowa kluczowego auto oraz odpowiedni komunikat o błędzie diagnostycznym emitowany przez kompilator.

Numer błędu opis
C3530 Słowo auto kluczowe nie może być łączone z żadnym innym specyfikatorem typu.
C3531 Symbol zadeklarowany za pomocą słowa kluczowego auto musi mieć inicjator.
C3532 Słowo kluczowe zostało auto niepoprawnie użyte do zadeklarowania typu. Na przykład zadeklarowaliśmy typ zwracany metody lub tablicę.
C3533, C3539 Nie można zadeklarować parametru lub argumentu szablonu za pomocą słowa kluczowego auto .
C3535 Nie można zadeklarować metody lub parametru szablonu za pomocą słowa kluczowego auto .
C3536 Nie można użyć symbolu przed jego zainicjowaniem. W praktyce oznacza to, że zmienna nie może być używana do inicjowania się.
C3537 Nie można rzutować do typu zadeklarowanego za pomocą słowa kluczowego auto .
C3538 Wszystkie symbole na liście deklaratorów zadeklarowane za auto pomocą słowa kluczowego muszą być rozpoznawane jako ten sam typ. Aby uzyskać więcej informacji, zobacz Deklaracje i definicje.
C3540, C3541 Operatory sizeof i typeid nie mogą być stosowane do symbolu zadeklarowanego za pomocą słowa kluczowego auto.

Przykłady

Te fragmenty kodu ilustrują niektóre sposoby użycia słowa kluczowego auto .

Następujące deklaracje są równoważne. W pierwszej instrukcji zmienna j jest zadeklarowana jako typ int. W drugiej instrukcji zmienna k jest wywoływana jako typ int , ponieważ wyrażenie inicjowania (0) jest liczbą całkowitą.

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

Następujące deklaracje są równoważne, ale druga deklaracja jest prostsza niż pierwsza. Jednym z najbardziej atrakcyjnych powodów używania słowa kluczowego auto jest prostota.

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

Poniższy fragment kodu deklaruje typ zmiennych iter , a elem po uruchomieniu for pętli i zakresu 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
    { /* ... */ }
}

Poniższy fragment kodu używa new operatora i deklaracji wskaźnika do deklarowania wskaźników.

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

Następny fragment kodu deklaruje wiele symboli w każdej instrukcji deklaracji. Zwróć uwagę, że wszystkie symbole w każdej instrukcji rozpoznają ten sam 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.

Ten fragment kodu używa operatora warunkowego (?:) do deklarowania zmiennej x jako liczby całkowitej, która ma wartość 200:

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

Poniższy fragment kodu inicjuje zmienną xinttypu , zmienną y do odwołania do typu const int, a zmienną fp do wskaźnika do funkcji zwracającej 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;
    //...
}

Zobacz też

Słowa kluczowe
/Zc:auto (Typ zmiennej deduce)
sizeof Operator
typeid
operator new
Deklaracje i definicje
Przykłady wyrażeń lambda
Inicjatory
decltype