C++ auto 关键字的使用

https://www.cnblogs.com/KunLunSu/p/7861330.html

C++98 auto

早在C++98标准中就存在了auto关键字,那时的auto用于声明变量为自动变量,自动变量意为拥有自动的生命期,这是多余的,因为就算不使用auto声明,变量依旧拥有自动的生命期:

int a =10 ;  //拥有自动生命期
auto int b = 20 ;//拥有自动生命期
static int c = 30 ;//延长了生命期

C++98中的auto多余且极少使用,C++11已经删除了这一用法,取而代之的是全新的auto:变量的自动类型推断。

C++11 auto

auto可以在声明变量的时候根据变量初始值的类型自动为此变量选择匹配的类型,类似的关键字还有decltype。举个例子:

    int a = 10;auto au_a = a;//自动类型推断,au_a为int类型cout << typeid(au_a).name() << endl;

typeid运算符可以输出变量的类型。程序的运行结果输出了

int

这种用法就类似于C#中的var关键字。auto的自动类型推断发生在编译期,所以使用auto并不会造成程序运行时效率的降低。而是否会造成编译期的时间消耗,我认为是不会的,在未使用auto时,编译器也需要得知右操作数的类型,再与左操作数的类型进行比较,检查是否可以发生相应的转化,是否需要进行隐式类型转换。

回到顶部

auto的用法

上面举的这个例子很简单,在真正编程的时候也不建议这样来使用auto,直接写出变量的类型更加清晰易懂。下面列举auto关键字的正确用法。

用于代替冗长复杂、变量使用范围专一的变量声明。

想象一下在没有auto的时候,我们操作标准库时经常需要这样:

#include<string>
#include<vector>
int main()
{std::vector<std::string> vs;for (std::vector<std::string>::iterator i = vs.begin(); i != vs.end(); i++){//...}
}

这样看代码写代码实在烦得很。有人可能会说为何不直接使用using namespace std,这样代码可以短一点。实际上这不是该建议的方法(C++Primer对此有相关叙述)。使用auto能简化代码:

#include<string>
#include<vector>
int main()
{std::vector<std::string> vs;for (auto i = vs.begin(); i != vs.end(); i++){//..}
}

for循环中的i将在编译时自动推导其类型,而不用我们显式去定义那长长的一串。

在定义模板函数时,用于声明依赖模板参数的变量类型。

template <typename _Tx,typename _Ty>
void Multiply(_Tx x, _Ty y)
{auto v = x*y;std::cout << v;
}

若不使用auto变量来声明v,那这个函数就难定义啦,不到编译的时候,谁知道x*y的真正类型是什么呢?

模板函数依赖于模板参数的返回值

template <typename _Tx, typename _Ty>
auto multiply(_Tx x, _Ty y)->decltype(x*y)
{return x*y;
}

当模板函数的返回值依赖于模板的参数时,我们依旧无法在编译代码前确定模板参数的类型,故也无从知道返回值的类型,这时我们可以使用auto。格式如上所示。
decltype操作符用于查询表达式的数据类型,也是C++11标准引入的新的运算符,其目的也是解决泛型编程中有些类型由模板参数决定,而难以表示它的问题。
auto在这里的作用也称为返回值占位,它只是为函数返回值占了一个位置,真正的返回值是后面的decltype(_Tx*_Ty)。为何要将返回值后置呢?如果没有后置,则函数声明时为:

decltype(x*y)multiply(_Tx x, _Ty y)

而此时x,y还没声明呢,编译无法通过。

回到顶部

注意事项

  • auto 变量必须在定义时初始化,这类似于const关键字。
  • 定义在一个auto序列的变量必须始终推导成同一类型。例如:

    auto a4 = 10, a5 = 20, a6 = 30;//正确
    auto b4 = 10, b5 = 20.0, b6 = 'a';//错误,没有推导为同一类型

    使用auto关键字做类型自动推导时,依次施加一下规则:

  • 如果初始化表达式是引用,则去除引用语义。

    int a = 10;
    int &b = a;auto c = b;//c的类型为int而非int&(去除引用)
    auto &d = b;//此时c的类型才为int&c = 100;//a =10;
    d = 100;//a =100;
  • 如果初始化表达式为const或volatile(或者两者兼有),则除去const/volatile语义。

    const int a1 = 10;
    auto  b1= a1; //b1的类型为int而非const int(去除const)
    const auto c1 = a1;//此时c1的类型为const int
    b1 = 100;//合法
    c1 = 100;//非法
  • 如果auto关键字带上&号,则不去除const语意。

    const int a2 = 10;
    auto &b2 = a2;//因为auto带上&,故不去除const,b2类型为const int
    b2 = 10; //非法

    这是因为如何去掉了const,则b2为a2的非const引用,通过b2可以改变a2的值,则显然是不合理的。

  • 初始化表达式为数组时,auto关键字推导类型为指针。

    int a3[3] = { 1, 2, 3 };
    auto b3 = a3;
    cout << typeid(b3).name() << endl;

    程序将输出

    int *

  • 若表达式为数组且auto带上&,则推导类型为数组类型。

    int a7[3] = { 1, 2, 3 };
    auto & b7 = a7;
    cout << typeid(b7).name() << endl;

    程序输出

    int [3]

  • 函数或者模板参数不能被声明为auto

    void func(auto a)  //错误
    {
    //...
    }
  • 时刻要注意auto并不是一个真正的类型。
    auto仅仅是一个占位符,它并不是一个真正的类型,不能使用一些以类型为操作数的操作符,如sizeof或者typeid。

    cout << sizeof(auto) << endl;//错误
    cout << typeid(auto).name() << endl;//错误

分类: C++

好文要顶 关注我 收藏该文  

自由真实个性
关注 - 2
粉丝 - 2

+加关注

4

0

« 上一篇:C++内存管理解析
» 下一篇:C++ 中std::function 、std::bind的使用和lambda的使用

posted @ 2017-11-19 20:12 自由真实个性 阅读(36986) 评论(1) 编辑 收藏

C++ auto 关键字的使用相关推荐

  1. auto关键字详解 C++

    C++98 auto 早在C++98标准中就存在了auto关键字,那时的auto用于声明变量为自动变量,自动变量意为拥有自动的生命期,这是多余的,因为就算不使用auto声明,变量依旧拥有自动的生命期: ...

  2. C++11 auto 关键字学习1

    在之前的 C++ 版本中,auto 关键字用来指明变量的存储类型,它和 static 关键字是相对的.auto 表示变量是自动存储的. C++11 中,使用它来做自动类型推导.也就是说,使用了 aut ...

  3. c++ auto 关键字

    C++11 赋予 auto 关键字新的含义,使用它来做自动类型推导.也就是说,使用了 auto 关键字以后,编译器会在编译期间自动推导出变量的类型,这样我们就不用手动指明变量的数据类型了 #inclu ...

  4. 【小白学习C++ 教程】二十、C++ 中的auto关键字

    @Author: Runsen 在 C++ 11 之前,每种数据类型都需要在编译时显式声明,在运行时限制表达式的值,但在 C++ 新版本之后,包含了许多关键字,允许程序员将类型推导留给编译器本身. 有 ...

  5. C++ auto关键字

    C++ auto关键字 1)编译器根据初始值判断变量类型 2)必须初始化 3)一条语句声明多个变量(只能有一个基本类型,const int和int属于不同类型)auto i = 0, *p = &am ...

  6. C++中auto关键字

    该博文为原创文章,未经博主同意不得转载,如同意转载请注明博文出处 本文章博客地址:https://cplusplus.blog.csdn.net/article/details/105010028 a ...

  7. C++起始(内联函数,宏的优缺点,const关键字,auto关键字(C++11)基于范围的for循环(C++11). 指针空值nullptr(C++11))

    内联函数 概念 以inline修饰的函数叫做内联函数,编译时C++编译器会在调用内联函数的地方展开,没有函数压栈的开销, 内联函数提升程序运行的效率 函数前增加inline关键字将其改成内联函数,在编 ...

  8. 关于C/C++中的“auto”关键字

    C/C++ 98标准 C++03标准 早在C++98标准中就存在了auto关键字,那时的auto用于声明变量为自动变量,自动变量意为拥有自动的生命期.此用法是多余的,因为即使定义变量时不加" ...

  9. 2-6:C++快速入门之内联函数,auto关键字,C++11基于范围的for循环和nullptr

    文章目录 一:内联函数 (1)宏函数的缺陷 (2)内联函数的概念 (3)内联函数的特性 二:auto关键字(C++11) (1)auto简介 (2)auto使用注意事项 三:基于范围的for循环(C+ ...

最新文章

  1. 区块链热度不减 应用风险不容忽视
  2. 做一个有姿态的女孩子
  3. electron builder 打包错误 cannot unpack electron zip file 解决方案
  4. #舍得Share#Flash Media Server4.5迅雷高速下载地址by lwxshow
  5. 腾讯2013年校园招聘笔试试题
  6. SpringMVC容器和Spring容器
  7. [译]如何在C#中调试LINQ查询
  8. java集合转js数值_前端js调用接口转换Map数组数据
  9. Quartz2D之绘制一个简单的机器猫
  10. 【干货】比赛后期大招之stacking技术分享
  11. Python – GitHub CentOS
  12. SPOJ7259(Light Switching)
  13. 581. Shortest Unsorted Continuous Subarray
  14. mysql 重放binlog_【MySQL】老版本重放binlog的罕见报错
  15. 人工智能?你需要了解的内容和AI学习路线
  16. c语言实现统计过程控制,SPC统计过程控制
  17. 安卓游戏广告加速插件_安卓迅游加速器,无需登陆免费加速,国内外游戏均可加速下载...
  18. ​RS232串口线常见接法与引脚定义
  19. 《软技能--代码之外的生存指南》学习笔记之自我营销篇
  20. MWC 2017:S8缺席,三星祭出AR/VR项目救场

热门文章

  1. int*p[ ]与int(*p)[ ]的不同
  2. 设置计算机网络为家用,两台电脑怎么同时上网 家用宽带路由器设置【设置方法】...
  3. phpinfo查看可以解析的后缀_配置nginx,Apache支持pathinfo模式-什么是phpinfo模式
  4. CDN 监控系统(二)
  5. 怎么修改与服务器的操作系统,怎么修改与服务器的操作系统
  6. Service Manger的初始化分析
  7. 专题2 文件系统结构
  8. html基础实验的实验原理,html网页设计实验报告.doc
  9. java线性表_java实现线性表
  10. mongodb安装_MongoDB索引策略和索引类型