auto 关键字(类型推导)

从该关键字的初始化表达式中推导变量的类型。

auto declarator initializer;

备注

auto关键字指示编译器使用一个声明的变量的初始化表达式推导其类型。

我们建议对大多数情况使用关键字 auto ,除非您非常需要转换,因为它提供这些优点:

  • 可靠性:,如果表达式的类型改变了--包括函数的返回类型改变了--它仍工作。

  • 性能: 确保不会出现转换。

  • 可用性测试: 不必担心类型名称拼写困难和排印错误。

  • 高效: 则代码会更高效。

您可能不希望使用 auto的转换大小写:

  • 当需要特定类型,并且不做其他操作。

  • 表达式模板帮助器类型 (例如、(valarray+valarray) 和初始值设定项列表,尽管您很少会选择编写 auto x = { 1 }; };和实际需要获取 int。

若要使用 auto 关键字,请声明一个关键字的变量而不是类型,并指定初始化表达式。 此外,还可以通过使用 const、 volatile、指针(*)、引用 (&) 以及 rvalue 引用 (&&) 等说明符和声明符来修改 auto 关键字。 该编译器将计算初始化表达式然后使用此信息推导变量的类型。

初始化表达式可以是分配 (等号语法),直接初始化 (函数样式语法),new 运算符 表达式,或者初始化表达式可以是在 基于范围的 for 语句 (C++) 语句的 for-range-declaration 参数。 有关详细信息,请参阅本主题后面部分的“服务器代码”一节初始值设定项

auto关键字是类型的占位符,但是,不是类型。 因此,auto 关键字不能用于转换或运算符(例如 sizeoftypeid)。

使用率

auto 关键字是一种声明具有复杂类型变量简单的方法。 例如,在初始化表达式涉及模板、函数的指针或成员的指针时使用 auto 来声明变量。

请使用auto声明变量并将变量初始化为 lambda 表达式。 您自己不能声明变量类型,因为只有编译器知道 lambda 表达式的类型。 有关详细信息,请参阅Lambda 表达式的示例

尾部的返回类型

请使用auto和decltype类型说明符帮助书写模板库。 使用 auto 和 decltype 声明一个模板函数,该函数的返回类型取决于其模板参数的类型。 或者,使用 auto 和 decltype 可以声明一个包装一个调用到另外一个函数的模板函数,然后返回不论是其他函数的返回类型。 有关详细信息,请参阅decltype 类型说明符

引用和 cv 限定符

请注意使用 auto 删除引用、常量限定符和变量的限定符。 请看下面的示例:

// 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放置。

限制和错误信息

下表列出了使用 auto 关键字的限制,和该编译器发出的对应的诊断错误消息。

错误号

描述

C3530

auto 关键字不能与其他任何类型说明符一起使用。

C3531

使用 auto 关键字声明的符号必须具有初始值设定项。

C3532

您已误用 auto 关键词来声明类型 例如,声明方法返回类型或数组。

C3533C3539

不能使用auto关键字声明参数或模板参数。

C3534

使用 auto 关键字并在 new 表达式内声明的符号必须具有初始值设定项。 有关详细信息,请参阅operator new (<new>)

C3535

不能使用auto关键字声明方法或模板参数。

C3536

不能在初始化之前使用的符号。 实际上,这意味着变量不能用来对自身进行初始化。

C3537

不能转换至有 auto 关键字声明的类型。

C3538

auto 关键字内声明的声明符列表的所有符号必须解析为同一类型。 有关详细信息,请参阅声明

C3540C3541

sizeoftypeid 运算符不能应用于用 auto 关键字声明的符号。

示例

这些代码段阐释 auto 关键字可以使用的一些用法。

下面的声明等效。 在第一个语句中,声明 j 变量为类型 int。 在第二个语句,因为初始化表达式 (0) 是整数,所以变量 k 推导为 int 类型。

   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 范围循环时,下面的代码片段声明 iter 和 elem 变量类型。

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

请参见

参考

auto 关键字

存储类说明符

C++ 关键字

/Zc:auto(推导变量类型)

sizeof 运算符

typeid

operator new (<new>)

声明

Lambda 表达式的示例

初始值设定项

decltype 类型说明符