Freigeben über


auto (C++)

Leitet den Typ einer deklarierten Variable vom entsprechenden Initialisierungsausdruck ab.

Hinweis

Der C++-Standard definiert eine ursprüngliche und eine überarbeitete Bedeutung für dieses Schlüsselwort. Vor Visual Studio 2010 deklariert das auto-Schlüsselwort eine Variable in der automatic-Speicherklasse, d. h. eine Variable, die über eine lokale Lebensdauer verfügt. Ab Visual Studio 2010 deklariert das auto-Schlüsselwort eine Variable, deren Typ aus dem Initialisierungsausdruck in der entsprechenden Deklaration abgeleitet wird. Die /Zc:auto[-]-Compileroption steuert die Bedeutung des auto-Schlüsselworts.

Syntax

auto Deklarator Initialisierer ;

[](auto param1 , auto param2 ) {};

Hinweise

Das auto-Schlüsselwort weist den Compiler an, den Initialisierungsausdruck einer deklarierten Variable oder einen Lambdaausdrucksparameter zu verwenden, um den Typ herzuleiten.

Es wird empfohlen, in den meisten Fällen das auto-Schlüsselwort zu verwenden (es sei denn, Sie möchten wirklich eine Konvertierung durchführen), denn diese Vorgehensweise bietet folgende Vorteile:

  • Stabilität:: Wenn der Typ des Ausdrucks geändert wird (dies schließt auch die Änderung eines Funktionsrückgabetyps ein), funktioniert der Vorgang weiterhin.

  • Leistung:: Sie haben die Sicherheit, dass keine Konvertierung durchgeführt wird.

  • Benutzerfreundlichkeit:: Sie müssen sich keine Gedanken um Schwierigkeiten und Fehler bei der Schreibweise der Typnamen machen.

  • Effizienz:: Ihre Codierung kann effizienter sein.

Fälle von Konvertierungen, bei denen Sie auto möglicherweise nicht verwenden sollten:

  • Wenn Sie einen ganz bestimmten Typ benötigen, und nichts anderes infrage kommt.

  • In Hilfstypen für Ausdrucksvorlagen, z. B. (valarray+valarray).

Wenn Sie das auto-Schlüsselwort verwenden, verwenden Sie es anstelle eines Typs, um eine Variable zu deklarieren, und geben Sie einen Initialisierungsausdruck an. Darüber hinaus können Sie das auto-Schlüsselwort mithilfe von Bezeichnern und Deklaratoren wie const, volatile, Zeigern (*), Verweisen (&) und rvalue-Verweisen (&&) ändern. Der Compiler wertet den Initialisierungsausdruck aus und verwendet dann diese Informationen, um den Typ der Variable herzuleiten.

Der auto Initialisierungsausdruck kann mehrere Formen annehmen:

  • Universelle Initialisierungssyntax, z. B. auto a { 42 };.
  • Zuordnungssyntax, z. B. auto b = 0;.
  • Universelle Zuordnungssyntax, die die beiden vorherigen Formulare kombiniert, z. B. auto c = { 3.14159 };.
  • Direkte Initialisierung oder Syntax im Konstruktorstil, z. B. auto d( 1.41421f );.

Weitere Informationen finden Sie unter Initialisierer und in den Codebeispielen, die später in diesem Dokument aufgeführt sind.

Wenn auto der Schleifenparameter in einer bereichsbasierten for Anweisung deklariert wird, wird eine andere Initialisierungssyntax verwendet, z. B. for (auto& i : iterable) do_action(i);. Weitere Informationen finden Sie unter Bereichsbasierte for-Anweisung (C++).

Das auto-Schlüsselwort ist ein Platzhalter für einen Typ, ist jedoch selbst kein Typ. Daher kann das auto-Schlüsselwort nicht in Umwandlungen oder Operatoren wie sizeof und (für C++/CLI) typeid verwendet werden.

Nützlichkeit

Das auto-Schlüsselwort ist eine einfache Möglichkeit, eine Variable zu deklarieren, die einen komplizierten Typ aufweist. Sie können beispielsweise auto verwenden, um eine Variable zu deklarieren, in der der Initialisierungsausdruck Vorlagen, Zeiger auf Funktionen oder Zeiger auf Member umfasst.

Sie können auto außerdem verwenden, um eine Variable zu deklarieren und auf einen Lambdaausdruck zu initialisieren. Sie können den Typ der Variable nicht selbst deklarieren, da der Typ eines Lambdaausdrucks nur dem Compiler bekannt ist. Weitere Informationen finden Sie unter Beispiele für Lambdaausdrücke.

Nachstehende Rückgabetypen

Sie können auto zusammen mit dem decltype-Typspezifizierer verwenden, um Vorlagenbibliotheken zu schreiben. Verwenden Sie auto und decltype, um eine Vorlagenfunktion zu deklarieren, deren Rückgabetyp von den Typen seiner Vorlagenargumente abhängt. Oder verwenden Sie auto und decltype, um eine Funktionsvorlage zu deklarieren, die einen Aufruf einer anderen Funktion umschließt und anschließend den Rückgabetyp dieser anderen Funktion zurückgibt. Weitere Informationen finden Sie unter decltype.

Verweise und CV-Qualifizierer

Verwenden von auto löscht Verweise, const Qualifizierer und volatile Qualifizierer. Betrachten Sie das folgende Beispiel:

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

Im vorherigen Beispiel ist myAuto ein int, kein int Verweis, sodass die Ausgabe 11 11 ist, nicht 11 12, wie der Fall wäre, wenn der Verweisqualifizierer nicht von auto gelöscht wurde.

Typabzug mit geschweiften Initialisierern (C++14)

Das folgende Codebeispiel zeigt, wie Sie eine auto Variable mit geschweiften Klammern initialisieren. Beachten Sie den Unterschied zwischen B und C und zwischen A und 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;
}

Beschränkungen und Fehlermeldungen

Die folgende Tabelle zeigt die Einschränkungen bei der Nutzung des auto-Schlüsselworts und die entsprechende Diagnosefehlermeldung, die der Compiler ausgibt.

Fehlernummer Beschreibung
C3530 Das auto-Schlüsselwort kann nicht mit einem anderen Typspezifizierer kombiniert werden.
C3531 Ein Symbol, das mit dem auto-Schlüsselwort deklariert wird, muss einen Initialisierer aufweisen.
C3532 Sie haben fälschlicherweise das auto-Schlüsselwort verwendet, um einen Typ zu deklarieren. Sie haben zum Beispiel einen Methodenrückgabetyp oder ein Array deklariert.
C3533, C3539 Ein Parameter oder ein Vorlagenargument kann nicht mit dem auto-Schlüsselwort deklariert werden.
C3535 Eine Methode oder ein Vorlagenparameter kann nicht mit dem auto-Schlüsselwort deklariert werden.
C3536 Ein Symbol kann nicht verwendet werden, bevor es initialisiert wird. In der Praxis bedeutet dies, dass eine Variable nicht verwendet werden kann, um sich selbst zu initialisieren.
C3537 Sie können nicht in einen Typ umwandeln, der mit dem auto-Schlüsselwort deklariert wird.
C3538 Alle Symbole in einer Deklaratorliste, die mit dem auto-Schlüsselwort deklariert wird, müssen in den gleichen Typ aufgelöst werden. Weitere Informationen finden Sie unter Deklarationen und Definitionen.
C3540, C3541 Die Operatoren sizeof und typeid können nicht auf ein Symbol angewendet werden, das mit dem auto-Schlüsselwort deklariert wird.

Beispiele

Die Codefragmente veranschaulichen einige Verwendungsmöglichkeiten des auto-Schlüsselworts.

Die folgenden Deklarationen sind gleichwertig. In der ersten Anweisung wird die j-Variable als Typ int deklariert. In der zweiten Anweisung wird die k-Variable hergeleitet, um Typ int zu entsprechen, da der Initialisierungsausdruck (0) eine ganze Zahl ist.

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

Die folgenden Deklarationen sind gleichwertig, die zweite Deklaration ist jedoch einfacher als die erste. Einer der überzeugendsten Gründe für die Verwendung des auto-Schlüsselworts ist die Einfachheit.

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

Das folgende Codefragment deklariert den Typ der Variablen iter und elem, wenn die Schleifen for und range-for beginnen.

// 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
    { /* ... */ }
}

Das folgende Codefragment verwendet den Operator und die Zeigerdeklaration new, um Zeiger zu deklarieren.

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

Im folgenden Codefragment werden mehrere Symbole in jeder Deklarationsanweisung deklariert. Beachten Sie, dass alle Symbole in jeder Anweisung in den gleichen Typ aufgelöst werden.

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.

Dieses Codefragment verwendet den bedingten Operator (?:), um die x-Variable als ganze Zahl mit einem Wert von 200 zu deklarieren:

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

Das folgende Codefragment initialisiert die x-Variable mit dem Typ int, die y-Variable mit einem Verweis auf Typ const int und die fp-Variable mit einem Zeiger auf eine Funktion, die den Typ int zurückgibt.

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

Weitere Informationen

Schlüsselwörter
/Zc:auto (Ableiten des Variablentyps)
sizeof-Operator
typeid
operator new
Deklarationen und Definitionen
Beispiele für Lambdaausdrücke
Initialisierer
decltype