该文为中国大学MOOC上北京邮电大学崔毅东和杨谈老师主讲的《C++程序设计(面向对象进阶)》笔记整理
1. auto 关键字
1. auto
- C++03 及之前的标准中,auto 放在变量声明之前,声明变量的存储策略,常省略不写
- C++11 中,auto 关键字放在变量前,作用是在声明变量的时候根据变量初始值类型自动为此变量选择匹配的类型
代码示例:
auto x{ 1 };
auto y{ 1.1 };
auto z = "ss";
2. auto 的使用限制
-
auto 变量必须在定义时初始化
auto x1{ 1 }; // 正确 auto x2; // 错误,编译器无法推导 x2 的类型 x2 = 10;
-
定义在一个 auto 序列的变量必须始终推导成同一类型
auto x1{10},x2{15}; // 正确 auto y1{12},y2{'c'}; // 错误,没有推导为同一类型
-
如果初始化表达式是引用或const,则去除引用或const语义
int x1{ 10 }; int& rx1 = x1; auto x = rx1; // 此时 x 的类型为 int 而非 int& const int y1{ 10 }; auto y = y1; // 此时 y 的类型为 int 而非 const int
-
如果 auto 关键字带上 &,则不去除引用或const语义
int x1{ 10 }; int& rx1 = x1; auto& x = rx1; // 此时 x 的类型是 int& const int y1{ 10 }; auto& y = y1; // 此时 y 的类型是 const int&
-
初始表达式为数组时,auto 关键字推导类型为指针
int a[3]{ 1,2,3 }; auto b = a; // 此时 b 的类型是 int *
-
若表达式为数组且 auto 带上 &,则推导类型为数组类型
int a[3]{ 1,2,3 }; auto& b = a; // 此时 b 的类型是 int[3] &
-
C++14中,auto 可以作为函数的返回值类型和参数类型
#include<iostream> auto max(int x,int y) { // 返回值类型为 auto return x > y ? x : y; } int main() { int x{ 1 }; int y{ 2 }; std::cout << max(1, 2) << std::endl; return 0; }
3. auto 使用建议
-
尽可能使用 auto,使用 auto 是为了代码的正确性、性能、可维护性、健壮性和方便,例如:保证在声明变量时即初始化
auto x{ 1 }; auto y; // 必须声明变量时初始化
-
当希望能在变量定义时,明确指出变量类型,且不希望随便更改其类型时,可以使用如下方法:
auto x = int{ 1 }; // 初始化列表 auto y = float{ 2.f }; // 初始化列表 auto z = int{ 1.1 }; // 编译器报错,初始化列表不能窄化
-
当 auto 和初始化列表一起用,要避免在一行中使用列表初始化和拷贝列表初始化
auto x{ 1 }, y = { 2 }; // 编译器报错,因为可能推导出不同类型
2. decltype 关键字
1. decltype
- decltype 利用已知类型声明新类型
- decltype 是在编译器推导表达式的类型,只做静态分析,不会导致已知类型表达式执行
- decltype 主要用于泛型编程(模板)
代码实例:
#include<iostream>
int func1() {
return 10;
}
auto func2() {
return 'a';
}
int main() {
decltype(func1()) x; // x 是 int 类型,func1() 并不会执行
decltype(func2()) y = func2();
return 0;
}
2. decltype与auto的对比
- auto 忽略最上层的 const,decltype 则保留最上层的 const
- auto 忽略原有类型的引用,decltype 则保留原有类型的引用
- 对解引用操作,auto 推断出原有类型,decltype 推断出引用
- auto 推断时自动执行,decltype 不会执行,只做分析