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时使用这个写法,因为不产生副本

 

posted @ 2022-05-30 14:59  namezhyp  阅读(194)  评论(0编辑  收藏  举报