自动 (C++)auto (C++)

从其初始化表达式中推导声明的变量的类型。Deduces the type of a declared variable from its initialization expression.

语法Syntax

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

备注Remarks

自动关键字指示编译器使用的声明的变量或 lambda 表达式参数初始化表达式来推导其类型。The auto keyword directs the compiler to use the initialization expression of a declared variable, or lambda expression parameter, to deduce its type.

我们建议你使用自动关键字大多数情况下的,除非您确实需要转换 — 因为它提供以下优势:We recommend that you use the auto keyword for most situations—unless you really want a conversion—because it provides these benefits:

  • 可靠性: 如果更改表达式的类型 — 这包括函数返回类型发生更改时,一切迎刃而解。Robustness: If the expression’s type is changed—this includes when a function return type is changed—it just works.

  • 性能: 您一定会进行任何转换。Performance: You’re guaranteed that there will be no conversion.

  • 可用性: 您无需担心类型名称拼写困难和拼写错误。Usability: You don't have to worry about type name spelling difficulties and typos.

  • 效率: 您的编码可能更有效。Efficiency: Your coding can be more efficient.

在其中可能不需要使用转换情况自动:Conversion cases in which you might not want to use auto:

  • 当需要特定类型且不需要执行任何其他操作时。When you want a specific type and nothing else will do.

  • 表达式模板帮助器类型 — 例如, (valarray+valarray)Expression template helper types—for example, (valarray+valarray).

若要使用自动关键字,使用它而不是一种类型来声明变量,并指定初始化表达式。To use the auto keyword, use it instead of a type to declare a variable, and specify an initialization expression. 此外,您可以修改自动使用说明符和声明符类似于关键字const易失性,指针 (*),引用 (&),和右值引用 (&&)。In addition, you can modify the auto keyword by using specifiers and declarators such as const, volatile, pointer (*), reference (&), and rvalue reference (&&). 编译器计算初始化表达式,然后使用该信息来推断变量类型。The compiler evaluates the initialization expression and then uses that information to deduce the type of the variable.

初始化表达式可以是赋值 (等号语法),直接初始化 (函数样式语法)、运算符 new表达式或初始化表达式可以是有关范围声明中的参数基于范围的语句 (C++)语句。The initialization expression can be an assignment (equal-sign syntax), a direct initialization (function-style syntax), an operator new expression, or the initialization expression can be the for-range-declaration parameter in a Range-based for Statement (C++) statement. 有关详细信息,请参阅初始值设定项和本文档后面的代码示例。For more information, see Initializers and the code examples later in this document.

自动关键字是类型的占位符,但它本身不是一种类型。The auto keyword is a placeholder for a type, but it is not itself a type. 因此,自动关键字不能使用强制转换或运算符如sizeof和 (对于C++/CLI) typeidTherefore, the auto keyword cannot be used in casts or operators such as sizeof and (for C++/CLI) typeid.

有用性Usefulness

自动关键字是声明具有复杂的类型的变量的简单方法。The auto keyword is a simple way to declare a variable that has a complicated type. 例如,可以使用自动来声明的变量的初始化表达式涉及模板、 指向函数的指针或指向成员的指针。For example, you can use auto to declare a variable where the initialization expression involves templates, pointers to functions, or pointers to members.

此外可以使用自动声明并初始化为 lambda 表达式的变量。You can also use auto to declare and initialize a variable to a lambda expression. 您不能自行声明变量的类型,因为仅编译器知道 lambda 表达式的类型。You can't declare the type of the variable yourself because the type of a lambda expression is known only to the compiler. 有关详细信息,请参阅Lambda 表达式的示例For more information, see Examples of Lambda Expressions.

尾部的返回类型Trailing Return Types

可以使用自动一起decltype类型说明符,以帮助编写模板库。You can use auto, together with the decltype type specifier, to help write template libraries. 使用自动decltype声明模板函数的返回类型取决于其模板自变量的类型。Use auto and decltype to declare a template function whose return type depends on the types of its template arguments. 或者,使用自动decltype声明包装对其他函数的调用,然后返回任何内容是函数的返回类型的模板函数。Or, use auto and decltype to declare a template function that wraps a call to another function, and then returns whatever is the return type of that other function. 有关详细信息,请参阅decltypeFor more information, see decltype.

引用和 cv 限定符References and cv-qualifiers

请注意,使用自动删除引用、 const 限定符和 volatile 限定符。Note that using auto drops references, const qualifiers, and volatile qualifiers. 请看下面的示例:Consider the following example:

// 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就会是这种情况,如果尚未删除引用限定符自动In the previous example, myAuto is an int, not an int reference, so the output is 11 11, not 11 12 as would be the case if the reference qualifier had not been dropped by auto.

具有大括号内的初始值设定项 (C++ 14) 的类型推导Type deduction with braced initializers (C++14)

下面的代码示例演示如何初始化使用大括号的自动变量。The following code example shows how to initialize an auto variable using braces. 请注意之间 A 和 B 和 C 之间的差异和 e。Note the difference between B and C and between A and 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;
}

限制和错误消息Restrictions and Error Messages

下表列出了对使用限制自动关键字和编译器发出的相应诊断错误消息。The following table lists the restrictions on the use of the auto keyword, and the corresponding diagnostic error message that the compiler emits.

错误号Error number 描述Description
C3530C3530 自动关键字不能与任何其他类型说明符组合。The auto keyword cannot be combined with any other type-specifier.
C3531C3531 使用声明的符号自动关键字必须具有初始值设定项。A symbol that is declared with the auto keyword must have an initializer.
C3532C3532 你错误地使用自动关键字来声明类型。You incorrectly used the auto keyword to declare a type. 例如,声明了方法返回类型或数组。For example, you declared a method return type or an array.
C3533C3539C3533, C3539 不能使用声明的参数或模板参数自动关键字。A parameter or template argument cannot be declared with the auto keyword.
C3535C3535 不能使用声明的方法或模板参数自动关键字。A method or template parameter cannot be declared with the auto keyword.
C3536C3536 符号初始化之前无法使用。A symbol cannot be used before it is initialized. 在实践中,这意味着无法使用变量来初始化自身。In practice, this means that a variable cannot be used to initialize itself.
C3537C3537 不能转换为与声明的类型,自动关键字。You cannot cast to a type that is declared with the auto keyword.
C3538C3538 使用声明的声明符列表中的所有符号自动关键字必须解析为同一类型。All the symbols in a declarator list that is declared with the auto keyword must resolve to the same type. 有关详细信息,请参阅声明和定义For more information, see Declarations and Definitions.
C3540, C3541C3540, C3541 Sizeoftypeid运算符不能应用于使用声明的符号自动关键字。The sizeof and typeid operators cannot be applied to a symbol that is declared with the auto keyword.

示例Examples

这些代码片段阐释了几种在其中自动可以使用关键字。These code fragments illustrate some of the ways in which the auto keyword can be used.

下面的声明等效。The following declarations are equivalent. 在第一个语句中,变量j被声明为类型int。在第二个语句中,变量k推导为类型int由于初始化表达式 (0) 是一个整数。In the first statement, variable j is declared to be type int. In the second statement, variable k is deduced to be type int because the initialization expression (0) is an integer.

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

以下声明等效,但第二个声明比第一个更简单。The following declarations are equivalent, but the second declaration is simpler than the first. 若要使用的最令人信服的原因之一自动关键字为简单起见。One of the most compelling reasons to use the auto keyword is simplicity.

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

下面的代码片段将声明的变量类型iterelem有关和范围循环启动。The following code fragment declares the type of variables iter and elem when the for and range for loops start.

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

使用下面的代码段运算符和指针声明来声明指针。The following code fragment uses the new operator and pointer declaration to declare pointers.

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

下一个代码片段在每个声明语句中声明多个符号。The next code fragment declares multiple symbols in each declaration statement. 请注意,每个语句中的所有符号将解析为同一类型。Notice that all of the symbols in each statement resolve to the same type.

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 的整数:This code fragment uses the conditional operator (?:) to declare variable x as an integer that has a value of 200:

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

下面的代码片段初始化变量x键入int、 可变y为引用类型const int,和变量fp为指向一个函数返回类型intThe following code fragment initializes variable x to type int, variable y to a reference to type const int, and variable fp to a pointer to a function that returns type 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;
    //...
}

请参阅See also

auto 关键字auto Keyword
关键字Keywords
/Zc:auto(推导变量类型)/Zc:auto (Deduce Variable Type)
sizeof 运算符sizeof Operator
typeidtypeid
运算符 newoperator new
声明和定义Declarations and Definitions
Lambda 表达式的示例Examples of Lambda Expressions
初始值设定项Initializers
decltypedecltype