C++的auto关键字

 一、auto关键字介绍

因为C++是静态类型语言,即会在编译阶段进行类型检查。我们知道对象的类型决定一个对象所能参与的操作,因此如果类型检查过程中发现试图执行对象类型不支持的操作,编译器将会报错。

这要求我们在声明变量时必须完整正确的指出变量的类型。然而当用某个表达式初始化变量,有时我们根本不知道这个表达式的类型到底是什么,因此也就没办法给变量声明和定义。关于这一点,下面会给出例子。

1.同时定义一个变量

为了解决该问题,C++11引入了auto类型说明符,让编译器去分析表达式所属的类型。具体做法如下:

auto intVal=12;

12是一个int类型的字面值常量,因此auto推断intVal的类型为int。借助vscode查看变量类型可以证明这一点:

2.同时定义多个变量

另外要注意的一点是,如果在一个语句用auto声明了多个变量,则初始化这些变量的表达式都必须使对应声明的变量的类型一致,如:

auto intVal=12,doubleVal=0.12;

12是一个int类型的字面值常量,因此intVal判断出来的是int类型,而0.12是一个double类型的字面值常量,因此doubleVal推断出来的是double类型,两者推断的类型不一致,因此这条语句错误。证明如下:

3.抛出疑问

注意上面的红字,那为什么不说表达式类型相同,表达式类型相同不就使得推断的类型相同了吗?

是的,表达式类型相同,推断的类型是会相同。但表达式类型不同,有时也会使得推断的类型相同,继续看。

二、auto注意点

编译器推断出来的auto类型有时候和表达式初始值的类型并不完全一样,编译器会适当地改变结果类型使其更符合初始化规则。如:

1.auto忽略引用

当初始值是一个引用时,auto推断的类型并不是引用,而是引用绑定的对象的类型:

int intVal=1;
int &refVal=intVal;
auto val=refVal;

借助vscode看到val的类型为int,而不是int&。

2.auto忽略顶层const

 当初始值是一个顶层const时,auto推断的类型将不会是顶层const类型。

const int cIntVal=12;
auto val=cIntVal;

借助vscode看到val的类型为int,而不是const int。

如果希望val是一个顶层const,则必须自己手动添加const类型修饰符:

const int cIntVal=12;
auto const val=cIntVal;

 借助vscode看到val的类型为const int。

3.auto不会忽略底层const

这一点比较好理解,代码如下:

const int intVal=12;
const int* intP1=&intVal;
auto intP2=intP1;

 借助vscode看到val的类型为const int*。

但需要注意的一点是,引用本身不是一个对象,因此常量引用其实是一个底层const,并不存在顶层const的说法,因此当auto去推断一个常量引用,同时声明的变量加了引用符(如果不加,推断的结果是引用绑定的对象去掉顶层const的类型),则推断的结果仍是常量引用,而不是普通引用,这符合C++不能使用非const引用绑定常量的语法规则。

const int intVal=12;
const int& ref1=intVal;
auto &ref2=ref1;
auto &ref3=12;

 借助vscode看到ref2的类型为const int&。

4.auto推断数组名 

数组名在C++很多场合下,都会转化为首元素地址,因此当auto推断的表达式是一个数组名的话,推断的结果是元素类型的指针。

int nums[3]={1,2,3};
auto p=nums;

  借助vscode看到p的类型为int*。

三、返回疑问

表达式类型不同,有时也会使得推断的类型相同:

const int cVal=1;
auto intVal1=2,intVal2=cVal;

代码在vscode上,并没有报错:

四、尾后置返回类型

 下面给出表达式类型未知的例子:

当我们使用C++模板写出下面的函数:

template<typename T, typename U>  
? add(T a, U b)
{  
    return a + b;  
}

请问a+b的类型是什么,我们根本没有办法确定a+b的类型。

因此为了应付这种情况,C++推出了尾后置返回类型,上面的函数正确的做法是:

template<typename T, typename U>  
auto add(T a, U b) -> decltype(a + b) 
{  
    return a + b;  
}

该做法意思是,当函数体执行完,再来判断函数的返回类型。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值