【C++】C++11新特性
一、auto类型推导
auto这个关键字其实在C++11之前就已经存在了,在C++98中的auto关键字的作用是指明变量的存储类型,与static相对,在比较老C++书籍中可以找得到相关内容,只是在我们的实际编程中基本上被忽略,这是因为我们在创建变量时默认的存储类型就是auto—自动存储类型的,不需要显示表示,只有在需要声明静态变量时才会显示表示static,以指明变量的存储类型为静态存储类型。如:
1 |
|
这里a和b的存储类型都是auto类型。
在C++11之后,C++标准摒弃了C++98的auto关键字的用法,将auto关键字的功能换成了自动类型推导,就和现在大多数脚本语言中的var一样。
需要注意的是,在自动类型推导中,小数会被默认推导成double类型而不是float。
auto的出现并不意味着C++变成了弱类型语言,auto在程序中仅仅只起到占位符的作用,在编译期间它才会被替换成具体的类型,所以在运行时类型依然是明确的。
auto关键字支持多变量声明,但是同时声明的变量必须是同一类型的,否则会出现编译不通过的错误。如:
1 |
|
这种情况会报错。
在声明auto变量时,必须对变量进行初始化。这种情况是语法错误:
1 |
|
auto、指针与引用
先来看一个例子:
1 |
|
输出结果:
1 |
|
可以看到auto推导出了指针类型,却忽略了&类型,这一点是需要注意的。
auto与const
还是先来看一个例子:
1 |
|
输出结果:
1 |
|
可以看到除了指针类型,其他的都被推导成了int类型,我们再在上面的代码中加一些代码:
1 |
|
当我们添加了这段代码之后,除了c1=2
,其他的行都会报语法错误,所以尽c2,r1,r2被推导为int类型,但是const的约束依旧存在,但是c1没有报语法错误,也就是说c1实际上是非const类型,即auto c1 = a
,在默认情况下auto将c1推导为非常量,如果需要设置为常量则需要显示标识const。
关于typeid().name()
有一点很迷,就是在C++的语法中,只有常量指针类型在类型名上带有const,如上面的int const *,而其他的无论是指针常量、常量引用在类型上都是忽略const的,但是在我们把一个变量常量的地址赋予一个非常量指针时,则会报:
在网上没有找到相关的解析,推测在C++语法上是只有常量指针类型带有const,没有其他的带有const的类型的,而出现上面的提示十有八九是编辑器做的,而非C++本身的。
总结
- auto的作用是类型推导,本质是占位符,在编译阶段,编译器会将正确的类型替换到auto位置上;
- auto可以和任何类型搭配,包括指针与引用;
- 在声明auto变量时必须对uto变量初始化;
- auto关键字可以用作函数返回值类型。
二、decltype类型推导
由于auto的使用在有些方面上收到限制,比如,声明auto变量时必须对变量进行初始化,而在实际使用时,可能没法进行初始化,于是decltype就出现了,decltype也是C++的一个关键字。
decltype通过表达式来推导类型,表达式可以是一个变量、常量、或者函数,使用形式为decltype(exp),exp为表达式
如:
1 |
|
和auto一样decltype也可以用作函数返回值类型。
decltype与auto的区别
- auto关键字声明的变量必须初始化,decltype不需要;
- auto在类中只能用于定义静态成员,decltype可以用于任何成员;
- decltype的使用上比auto更灵活;
- auto更具初始值来推导类型,decltype根据表达式来推导类型。
三、返回类型后置语法
有时候我们写函数需要用到函数参数来推导,由于C++的返回值是前置语法,所以返回值是无法使用函数参数的,于是便有了返回值类型后置语法,先看一个例子:
1 |
|
返回值类型后置语法可以将decltype使用参数推导出的类型赋予auto中,所以在这个语法中auto,decltype是必不可少的。
我们仔细思考后会发现好像直接这样使用也是可以达到最终效果的:
1 |
|
那么返回值后置类型语法的作用又是什么呢?事实上我们在多想一下就会明白,auto fun(T a,U b)->decltype(a+b)
语法把auto的类型限制在decltype(a+b)的推导类型的范围内了,而auto fun(T a,U b)中auto是可以为任何类型的。但是在大多数使用场景下似乎还是没什么区别。
到这里只有一句感叹,C++在类型推导上相较于主流脚本语言的类型推导还是薄弱了很多很多。
四、左值与右值
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!