共用方式為


auto (C++)

從所宣告變數的初始化運算式,來推斷其類型。

注意

C++ 標準為此關鍵字定義了原始和修訂的意義。 在 Visual Studio 2010 前,auto 關鍵字會在自動儲存體類別中宣告變數,也就是具有區域存留期的變數。 從 Visual Studio 2010 開始,auto 關鍵字則會宣告一個變數,從類型是其宣告的初始化運算式推算而來。 /Zc:auto[-] 編譯器選項可控制 auto 關鍵字的意義。

語法

auto 宣告子 初始設定式 ;

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

備註

auto 關鍵字會指示編譯器使用所宣告變數或 Lambda 運算式參數的初始化運算式來推算其類型。

除非您確實要進行轉換,否則建議您在大多數情況下使用 auto 關鍵字,因為它提供下列優點:

  • 穩固性:如果運算式的類型變更 (這包括函式傳回型別變更時),它就會運作。

  • 效能:可保證不會進行任何轉換。

  • 可用性:您不需要擔心類型名稱拼字困難和拼錯字。

  • 效率:您的程式碼可能較具效率。

可能不想使用 auto 的轉換案例:

  • 想要特定類型但不執行任何動作時。

  • 例如,在運算式範本協助程式類型中的(valarray+valarray)

若要使用 auto 關鍵字,請使用它 (而非類型) 來宣告一個變數,並指定初始化運算式。 此外,您還可以修改 auto 關鍵字,方式是使用規範和宣告子,例如 constvolatile、指標 (*)、參考 (&) 和右值參考 (&&)。 編譯器會評估初始化運算式,然後使用該資訊來推斷變數類型。

auto 初始化運算式可以採用數種形式:

  • 通用初始化語法,例如 auto a { 42 };
  • 指定語法,例如 auto b = 0;
  • 通用指派語法,結合上述兩種形式,例如 auto c = { 3.14159 };
  • 直接初始化,或建構函式樣式語法,例如 auto d( 1.41421f );

如需詳細資訊,請參閲本文件稍後的初始化和程式碼範例。

auto 用來在範圍型 for 陳述式中宣告迴圈參數時,它會使用不同的初始化語法,例如 for (auto& i : iterable) do_action(i);。 如需詳細資訊,請參閱 範圍型 for 陳述式 (C++)

auto 關鍵字是類型的預留位置,但它本身不是類型。 因此,auto 關鍵字不能用於轉換或運算子 (例如 sizeof 和 (適用於 C++/CLI) typeid)。

實用性

auto 關鍵字是宣告包含複雜類型之變數的簡單方式。 例如,您可以使用 auto 來宣告變數,其中初始化運算式包括範本、函式指標或成員指標。

您也可以使用 auto 宣告並初始化 Lambda 運算式的變數。 您無法自行宣告變數類型,因為只有編譯器才知道 Lambda 運算式的類型。 如需詳細資訊,請參閱 Lambda 運算式的範例

尾端傳回型別

您可以搭配使用 autodecltype 類型規範,以協助撰寫範本程式庫。 使用 autodecltype 來宣告其傳回型別視範本引數而定的函式範本。 或是使用 autodecltype 宣告函式範本,以包裝對其他函式的呼叫,然後傳回該其他函式的傳回型別。 如需詳細資訊,請參閱decltype

參考和 cv 限定詞

使用 auto 會卸除參考、const 限定詞和 volatile 限定詞。 請考慮下列範例:

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

在上一個範例中,myAuto 是 int,而不是 int 參考,因此輸出是 11 11 而不是 11 12 (如果參考限定詞尚未由 auto 卸除的情況時會是這樣)。

使用括號初始設定式進行類型推算 (C++14)

下列程式碼範例將示範如何使用括號初始化 auto 變數。 請注意 B 和 C 與 A 與 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;
}

限制和錯誤訊息

下表會列出 auto 關鍵字使用限制,以及編譯器所發出的對應診斷錯誤訊息。

錯誤號碼 描述
C3530 auto 關鍵字無法與任何其他類型規範結合。
C3531 使用 auto 關鍵字所宣告的符號必須有初始設定式。
C3532 您不正確地使用 auto 關鍵字來宣告類型。 例如,您已宣告方法傳回類型或陣列。
C3533C3539 參數或範本引數不可以使用 auto 關鍵字進行宣告。
C3535 方法或範本參數不可以使用 auto 關鍵字進行宣告。
C3536 符號無法在初始化之前使用。 實際上,這表示不能使用變數來初始化它自己。
C3537 您無法轉換成使用 auto 關鍵字所宣告的類型。
C3538 宣告子清單中使用 auto 關鍵字所宣告的所有符號必須解析成相同的類型。 如需詳細資訊,請參閱宣告和定義
C3540C3541 sizeoftypeid 運算子不能套用至使用 auto 關鍵字所宣告的符號。

範例

這些程式碼片段說明了使用 auto 關鍵字的數種方式。

下列宣告相同。 在第一個陳述式中,變數 j 會宣告成類型 int。 在第二個陳述式中,變數 k 會推斷成類型 int,因為初始化運算式 (0) 是整數。

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

下列宣告相同,但第二個宣告比第一個宣告簡單。 其中一個使用 auto 關鍵字的最令人信服原因是簡單。

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

下列程式碼片段會在 for 和範圍 for 迴圈開始時宣告變數 iterelem 的類型。

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

下列程式碼片段會使用 new 運算子和指標宣告來宣告指標。

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

下一個程式碼片段會宣告每個宣告陳述式中的多個符號。 請注意,每個陳述式中的所有符號都會解析成相同類型。

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.

此程式碼片段使用條件運算子 (?:) 將變數 x 宣告為值為 200 的整數:

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

下列程式碼片段會將變數 x 初始化成類型 int、變數 y 初始化成類型 const int 的參考,以及將變數 fp 初始化成可傳回型別 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;
    //...
}

另請參閱

關鍵字
/Zc:auto (推算變數類型)
sizeof運算子
typeid
operator new
宣告和定義
Lambda 運算式的範例
初始設定式
decltype