8.1 关键字:auto

C++98中auto用法(C++11已废弃)

C++98 auto用于声明变量为自动变量(拥有自动的生命周期),C++11已经删除了该用法,取而代之的是“变量的自动类型推断方法”。

// c++ 98:
int a = 10;         // 拥有自动生命期
auto int b = 20;    // 拥有自动生命期(C++11编译不过)
static int c = 30;  // 延长了生命期

C++11新标准引入了auto类型说明符,让编译器通过初始值来自动推断变量类型(这意味着通过auto定义的变量必须有初始值)。

// c++ 11:
int a = 10;
auto auto_a = a;  // 自动类型推断为int类型

auto会去除变量的引用语义

当引用对象作为初始值时,真正参与初始化的是引用对象的值,此时编译器会以引用对象的类型作为auto推算的类型:

int main(void) {
    int i = 10;
    int &ri = i;
    auto auto_i = ri;  // 去除引用语义, 自动推断为int
}

如果希望推断出来的auto类型包含引用语义,我们需要用&明确指出:

int main(void) {
    int i = 10;
    auto &auto_i = i;  // 加上引用语义, 自动推断为int&
}

auto忽略顶层const

auto一般会忽略掉顶层const,同时底层const会被保留下来:

int main(void) {
    const int ci = 10;    // 常量int
    auto auto_ci = ci;    // auto_ci被推断为int类型
    auto_ci = 20;         // 正确: auto_ci非常量

    const int &cr = ci;   // cr是指向常量int的常量引用
    auto auto_cr = cr;    // auto_cr被推断为int类型: 去除了引用语义 + 去除了顶层const
    auto_cr = 20;         // 正确: auto_cr非常量

    const int *cp = &ci;  // cp是指向常量int(底层)的常量指针(顶层)
    auto auto_cp = cp;    // auto_cp被推断为const int*类型(指向常量int的指针): 去除了顶层const + 保留底层const
    // *auto_cp = 10;     // 错误: 不能修改auto_cp指向的常量
}

如果希望推断出来的auto类型是一个顶层const,我们需要通过const关键字明确指出:

int main(void) {
    const int ci = 10;          // 常量int
    const auto auto_ci = ci;    // auto_ci被推断为const int类型
    // auto_ci = 20;            // 错误: auto_ci是一个常量, 禁止修改
}

如果用auto关键字带上&,也不会去除顶层const:

const int i = 10;

auto &j = i;  // auto&不去除顶层const语义, j类型被推断为const int
j = 10;       // 非法