C++11新特性之auto的妙用
C++11引入了auto和decltype关键字实现类型推导,通过这两个关键字不仅能方便地获得复杂的类型,还能简化书写,提高编码效率。下面说一下C++中的auto
旧标准
auto其实并不是一个新的关键字,在旧的标准C++98/03中,它代表着“具有自动存储周期的局部变量”。啥意思呢?就是我们平常所说的变量,他与static相对。就是说所有非static类型的都是“具有自动存储期的”。也就是说在旧的标准下。
autoint i =3;//等价于int i=3;
新标准
在C++11中,auto作为一个新的类型指示符(如int,double)来指示编译器的,但是auto申明的变量的类型必须由编译器在编译时期推导出来,也称类型推导。这种类型推导不是C++所独有的,还有很多具备这种能力的语言(如Python,Javascript)。我们先来看一段Python代码
name ="thinkmoon"print"hello,"+ name
在这里的name是不需要定义类型的,因为这个类型很容易被推导为字符串性,如过要想在C++中实现这种效果,我们可以这样。
#include<iostream>
int main(){
auto name ="thinkmoon";
std::cout <<"hello,"<< name << std::endl;
return0;
}
效果是一样的,是不是觉得写起来特别的方便呢?
但是需要注意的是,在C++中这种静态类型推导是发生在编译期间的。而像Python这种动态类型推导却是发生在运行期间的。
auto的基本用法
#include<iostream>
usingnamespace std;
int main(){
auto x =5;
cout << x << endl;//x被推导为intauto p =newauto(1);
cout <<"*"<< p <<"="<<*p << endl;//p被推导为
int *constauto*v =&x, u =6;
cout <<"*"<< v <<"="<<*v <<"\n u="<< u << endl;//v被推导为const int *,u被推导const int
}
对于最后一个类型推导有几个需要注意
- v被推导为const int *而这里auto代替int,但是u等于6还是要写的,否则编译器会报错。
- u的等号后面只能写整型的变量,否则会报错,因为不能让编译器产生具有二义性的推断。
其实我们学习的时候可以把auto理解为占位符,它只是占着一个位置并不做其它的事情,由编译器将其类型推导出来再用对应的类型去运行,所以这个时候auto的类型推导是不能让编译器产生二义性的。
auto的推导规则
int x =0;auto* a =&x;//auto推导为int,
auto b =&x;//auto推导为int *,即使不申明为指针也能推断为指针
auto& c = x;//auto推导为int,等价于int
auto d = c;//auto推导为int,auto会抛弃右值的引用类型
const auto e = x;//e是const int类型,
auto f = e;//f是int型constauto&g = x;//g是const
int & auto & h = g; //h是const int &
总结:
- 当不申明为引用或者指针时,auto的推导规则会抛弃对应右值的cv限定符(cv-qualifier,const,volatile限定符的总称)。
- 当申明为引用或者指针时,auto推导规则会保留右值的cv属性。
auto的限制
- auto s
错误原因:s没有明确的类型,auto无法推断。
- void fun(auto a=1){….}
错误原因:auto类型推导不能用作函数参数。
- auto不能用于非静态成员函数
struct Foo
{
auto var_1=0;//错误,auto不能用于非静态成员函数
static const auto var_2=0;//OK,var_2为static const int
}
4. auto无法定义数组
int main()
{
int arr[10]={0};
auto aa = arr; //OK,aa为int *
auto bb[10]=arr;//error,auto无法定义数组
}
5. auto无法推导出模板参数
Bar<int> bar;
Bar<auto> bb = bar;//error,auto无法推导出模板参数
auto的优势
既然auto的功能特性这么方便,那么它的优势在哪?或者说,我们什么时候使用它能达到神效呢?
- 遍历vector
这是一个简单的遍历。
vector<int> vs;for(auto i = vs.begin(); i < vs.end(); i++){......}
其实还可以更简单
for(auto var : vs){.......}
- 待补充。。。。。。。嘿嘿!
版权声明: (https://www.thinkmoon.cn/post/77)
本文首发于指尖魔法屋-C++11新特性之auto的妙用
转载或引用必须申明原指尖魔法屋来源及源地址!