C++ auto关键词的理解
参考文章:C++ auto用法及应用详解_代码乌龟的博客-CSDN博客_c++auto
C++11特性:auto关键字 - melonstreet - 博客园 (cnblogs.com)
底层const顶层const到底是什么?_代码乌龟的博客-CSDN博客_什么是顶层const
https://blog.csdn.net/Function_Dou/article/details/86532374
c++11以前,auto在C++里面的作用是自动判断变量的生命周期。但是变量不加static等关键词一样会自动判断声明周期(离开函数后被销毁)。所以C++11后,auto被赋予了新的功能:自动判断变量类型。
这个过程在编译期就会执行。不占用程序的运行时间。
用法:
1. 放在暂时无法确定类型的变量名前,代替int、double等类型。但是auto并不是一个真的类型,它无法使用typeid、sizeof等操作符。
2. 代替一些冗长的类型名;
3. 配合模板使用。有时候模板中声明出的变量在写模板时也无法确定类型,可以使用auto;
4. 配合模板函数使用,表示返回值。(此时auto也只能起到占位作用)
-----------------------------------
实例:
int a=10; auto b=a; //b会被自动推断为int型
以上是一个比较基础的理解,一般也不会有人这样使用它。在实际中,它可以代替一些比较长的类型名:
for(list<int>::iterator i = l1.begin(); i!=l1.end();i++) { cout<<i.operator->()<<endl; }
我们可以直接auto i=l1.begin() 编译器会自动识别。
除此之外,auto配合模板使用,可以推迟类型的获取
template <typename _Tx,typename _Ty> void Multiply(_Tx x, _Ty y) { auto v = x+y; std::cout <<v; }
v在模板中被声明,无法确定其类型,只能等到实际使用模板时才能确定,所以使用auto占位。此外,auto也可以用来修饰返回值,推迟实际返回值的判断
template <class T1,class T2> auto func(T1 t1,T2 t2)->decltype(*t1) { ... }
使用auto将返回值放在最后,这里auto的作用即返回值占位。
但是注意,auto不能用来声明模板函数里面形参的类型
void func(auto a) //报错 { }
-----------------------
auto的具体用法和识别规则:
除过上面提到的用法,auto在使用过程中还存在一些规则和用法:
首先 先提一下顶层const和底层const。const关键词会让被标记的其他关键词或变量不可被修改,变为常量,根据修饰的不同,产生了顶层const和底层const之分。
顶层const:const在修饰指针变量时,const直接修饰指针,即指针本身值不能变,即不能改变指针的指向。这就是顶层const。
底层const:修饰指针变量时,const修饰指针指向地址的那个值。即指针指到的内存位置,值不能再改变。这就是底层const。
区分这个也很容易,const修饰的关键词可以按照就近原则去记忆:
int* const p1=&a; //const修饰p1,p1本身的值不能再改,p1是顶层const
const int* p2=&a //const修饰int* p2,a的值不能再改,p2是底层const
1. 顶层const赋值给其他变量时,可以忽略顶层属性;底层const缺不能忽略底层属性。
2. int* 类型(此处举例都是int) 可以转换为顶层/底层const,可以给二者赋值。
3. 底层const无法转换为顶层const。
说完了const的规则,再回到auto。
auto在使用时不仅仅是单个存在,它也经常会与const &等连用。
使用规则如下:
1. 如果修饰变量时,右带了引用,那么要去掉引用含义,也就是说生成了一个新变量。想要引用可以使用auto&
int a=10; int &b=a; auto c=b; //c是int型,去掉了引用 auto &d=b; //d是引用 int&
2. 如果修饰时,右侧变量带有const/volatile两者均有 ,除去二者语义
如果需要const,就把auto换成const auto。(换句话说,auto会忽略引用和顶层const)
const int a1=10; auto b1=a1; //b1是int型 const auto c1=a1; //c1受外面影响,变成const int
但如果auto带了&,那么不去掉const语义。因为auto&还是相当于一个引用,一个常量不可以通过这种方式又被改变值。
const int a2=10; auto &b2=a2; //b2是a2的引用,b2是const int b2=10; //报错,常量不可修改
右侧为数组时,auto关键字推导得到指针。但如果用auto& ,那么推导出的是数组
int a3={1,2,3}; auto b=a3; //b是int* auto& b2=a3; //b2是int[3]
auto与for
for(auto i:range) // range中的每个元素都会产生副本 for(const auto i:range) //range中的每个元素都会产生副本,但副本不可被修改 for(auto &i :range) //直接引用range的元素,修改时也修改原来的值 for(const auto& i:range) // 直接引用range里的元素,且不能修改。一般初始化左值并且需要读取range时使用这个写法,因为不产生副本