auto (C++)

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

注意

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

語法

autodeclaratorinitializer;

[](autoparam1 , auto param2) {};

備註

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

我們建議您在大部分情況下使用 auto 關鍵字,除非您真的想要轉換,因為它提供下列優點:

  • 健全性: 如果運算式的類型已變更,包括函式傳回型別變更時,它就可正常運作。

  • 效能: 您保證沒有轉換。

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

  • 效率: 您的程式碼撰寫更有效率。

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

  • 您想要特定類型,且不會執行任何其他動作。

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

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

初始化 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;
}

在上一 int 個範例中,myAuto 是 ,不是 int 參考,因此輸出為 11 11 ,如果參考限定詞尚未由 卸載 auto ,則不會 11 12 像 這樣。

使用大括弧初始化運算式的類型推算 (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 關鍵字來宣告類型。 例如,您已宣告方法傳回類型或陣列。
C3533 C3539 參數或範本引數無法使用 關鍵字宣告 auto
C3535 無法使用 關鍵字宣告 auto 方法或範本參數。
C3536 在初始化符號之前,無法使用符號。 實際上,這表示變數無法用來初始化本身。
C3537 您無法轉換成以 關鍵字宣告的類型 auto
C3538 auto 關鍵字宣告的宣告子清單中的所有符號都必須解析為相同的類型。 如需詳細資訊,請參閱 宣告和定義
C3540 C3541 sizeof typeid 運算子無法套用至以 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();

下列程式碼片段會宣告變數 iter 的類型,以及 elemfor 當 和 範圍 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
    { /* ... */ }
}

下列程式碼片段會使用 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 、類型之參考的 const int 變數 y ,以及傳回型 int 別 之函式的指標變數 fp

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