auto 关键字
1 介绍
编程时常常需要把表达式的值赋给变量,这就要求在声明变量时清楚地知道表达式的类型。然而要做到这一点并非那么容易,有时甚至做不到。如下:
- 类型难于拼写
- 含义不明确导致容易出错
#include <string>
#include <map>
int main()
{
std::map<std::string, std::string> m{ { "apple", "苹果" },
{ "orange","橙子" },
{"pear","梨"} };
std::map<std::string, std::string>::iterator it = m.begin();
while (it != m.end())
{
//....
}
return 0;
}
std::map<std::string, std::string>::iterator 是一个类型,但是该类型太长了,特别容易写错
为了解决这个问题,C 11完善了auto类型。通过使用它,就能让编译器替我们去分析表达式所属的类型。
C 11中,标准委员会赋予了auto全新的含义:
auto不再是一个存储类型指示符,而是作为一个新的类型指示符来指示编译器,auto声明的变量必须由编译器在编译时期推导而得
2 使用细则
使用auto定义变量时必须对其进行初始化,在编译阶段编译器需要根据初始化表达式来推导auto的实际类型。因此 auto 并非是一种“类型”的声明,而是一个类型声明时的“占位符”,编译器在编译期会将auto替换为变量实际的类型
- auto与指针和引用结合起来使用 用auto声明指针类型时,用auto和auto*没有任何区别,但用auto声明引用类型时则必须加&
- 在同一行定义多个变量 当在同一行声明多个变量时,这些变量必须是相同的类型,否则编译器将会报错,因为编译器实际只对第一个类型进行推导,然后用推导出来的类型定义其他变量。
#include<typeinfo>
#include<iostream>
using namespace std;
int main() {
int x = 10;
auto a = 1,b = 5;//前后一致可以
auto c = 10,d = 1.0;//这样会报错,因为c和d的初始化表达式类型不同
return 0;
}
3 注意事项
auto有不能被推导的情况:
- auto不能作为函数的参数
void add(auto a, auto b){
//这样不能通过编译!!!
}
- auto不能直接用来声明数组
void TestAuto()
{
int a[] = {1,2,3};
auto b[] = {4,5,6};//这样会报错!!!
}
- 为了避免与C 98中的auto发生混淆,C 11只保留了auto作为类型指示符的用法
- auto在实际中最常见的优势用法C 11提供的新式for循环,还有lambda表达式等进行配合使用
- 切记不要过度使用auto 关键字,不然代码的可读性会大大折扣!!!
#include<iostream>
using namespace std;
auto func(){
//...
if(){
//...
return a;
}
else if(){
//...
if(){
//...
return b;
}
//...
return c;
}
//...
}
int main() {
auto add = func();
}
像这样多上几个嵌套,就不好确认数据类型,让代码可读性大打折扣!!!