自动类型扣除

Version >= C++ 11

使用 auto 关键字进行类型推导与模板类型推导几乎相同。以下是一些例子:

auto x = 27;           // (x is neither a pointer nor a reference), x's type is int
const auto cx = x;     // (cx is neither a pointer nor a reference), cs's type is const int
const auto& rx = x;    // (rx is a non-universal reference), rx's type is a reference to a const int

auto&& uref1 = x;      // x is int and lvalue, so uref1's type is int&
auto&& uref2 = cx;     // cx is const int and lvalue, so uref2's type is const int &
auto&& uref3 = 27;     // 27 is an int and rvalue, so uref3's type is int&&

差异概述如下:

auto x1 = 27;          // type is int, value is 27
auto x2(27);           // type is int, value is 27
auto x3 = { 27 };      // type is std::initializer_list<int>, value is { 27 }
auto x4{ 27 };         // type is std::initializer_list<int>, value is { 27 }
                       // in some compilers type may be deduced as an int with a 
                       // value of 27. See remarks for more information.
auto x5 = { 1, 2.0 }   // error! can't deduce T for std::initializer_list<t>

正如你所看到的,如果使用支撑初始化器,则会强制 auto 创建 std::initializer_list<T> 类型的变量。如果它无法推断出 T,则代码被拒绝。

auto 用作函数的返回类型时,它指定该函数具有尾随返回类型

auto f() -> int {
    return 42;
}

Version >= C++ 14

除了 C++ 11 中允许的自动使用外,C++ 14 还允许以下内容:

  1. 当用作没有尾随返回类型的函数的返回类型时,指定函数的返回类型应该从函数体中的 return 语句推导出来(如果有的话)。

    // f returns int:
    auto f() { return 42; }
    // g returns void:
    auto g() { std::cout << "hello, world!\n"; }
    
  2. 在 lambda 的参数类型中使用时,将 lambda 定义为通用 lambda

    auto triple = [](auto x) { return 3*x; };
    const auto x = triple(42); // x is a const int with value 126
    

特殊形式 decltype(auto) 使用 decltype 的类型演绎规则而不是 auto 的类型演绎规则。

int* p = new int(42);
auto x = *p;           // x has type int
decltype(auto) y = *p; // y is a reference to *p

在 C++ 03 及更早版本中,auto 关键字作为从 C 继承的存储类说明符具有完全不同的含义。