一. auto简介

编程时候常常需要把表达式的值付给变量,需要在声明变量的时候清楚的知道变量是什么类型。然而做到这一点并非那么容易(特别是模板中),有时候根本做不到。为了解决这个问题,C++11新标准就引入了auto类型说明符,用它就能让编译器替我们去分析表达式所属的类型。和原来那些只对应某种特定的类型说明符(例如 int)不同。auto 让编译器通过初始值来进行类型推演。从而获得定义变量的类型,所以说 auto 定义的变量必须有初始值。

//由val_1 和val_2相加的结果可以推断出item的类型
auto item = val_1 + val_2;//item 类型初始化为val_1 + val_2相加后的类型,值为val_1+val_2相加的值。     这里的 item 的类型是编译器在编译的过程中通过val_1和val_2的类型相加后推算出来的。假如是val_1(int) + val_2(double),那么item的类型就是double.             使用auto也能在一个语句中声明多个变量,因为一个声明雨具只能有一个基本数据类型,所以该雨具所有变量的初始基本数据类型都必须是一样的。在这里一定要区别数据类型和类型修饰符!! int i = 3;
auto a = i,&b = i,*c = &i;//正确: a初始化为i的副本,b初始化为i的引用,c为i的指针.
auto sz = 0, pi = 3.14;//错误,两个变量的类型不一样。             编译器推断出来的auto类型有时候会跟初始值的类型并不完全一样,编译器会适当的改变结果类型使得其更符合初始化规则。
            首先,正如我们熟知的,使用引用其实是使用引用的对象,特别当引用被用作初始值的时候,真正参与初始化的其实是引用对象的值。此时编译器以引用对象的类型作为auto的类型: int i = 0 ,&r = i;//定义一个整数i,并且定义r为i的应用.
auto a = r; //这里的a为为一个整数,其值跟此时的i一样.             由此可以看出auto会忽略引用,其次,auto一般会忽略掉顶层const,但底层const会被保留下来,比如当初始值是一个指向常量的指针时:
  int i = 0;
const int ci = i, &cr = ci; //ci 为整数常量,cr 为整数常量引用
auto a = ci; // a 为一个整数, 顶层const被忽略
auto b = cr; // b 为一个整数,顶层const被忽略
auto c = &ci; // c 为一个整数指针.
auto d = &cr; // d 为一个指向整数常量的指针(对常量对象区地址是那么const会变成底层const)             如果你希望推断出auto类型是一个顶层的const,需要明确指出: const auto f = ci;             还可以将引用的类型设为auto,此时原来的初始化规则仍然适用(用于引用声明的const都是底层const): auto &g = ci; //g是一个整数常量引用,绑定到ci。
auto &h = 42; // 错误:非常量引用的初始值必须为左值。
const auto &j = 42; //正确:常量引用可以绑定到字面值。 二. decltype简介             有的时候我们还会遇到这种情况,我们希望从表达式中推断出要定义变量的类型,但却不想用表达式的值去初始化变量。还有可能是函数的返回类型为某表达式的的值类型。在这些时候auto显得就无力了,所以C++11又引入了第二种类型说明符decltype,它的作用是选择并返回操作数的数据类型。在此过程中,编译器只是分析表达式并得到它的类型,却不进行实际的计算表达式的值。 decltype(f()) sum = x;// sum的类型就是函数f的返回值类型。
          
            在这里编译器并不实际调用f函数,而是分析f函数的返回值作为sum的定义类型。             基本上decltype的作用和auto很相似,就不一一列举了。对于decltype还有一个用途就是在c++11引入的后置返回类型。 三. decltype 和 auto 区别             decltype在处理顶层const和引用的方式与auto有些许不同,如果decltype使用的表达式是一个变量,则decltype返回该变量的类型(包括顶层const和引用在内)。 const int ci = 42, &cj = ci; decltype(ci) x = 0; // x 类型为const int
auto z = ci; // z 类型为int decltype(cj) y = x; // y 类型为const int&
auto h = cj; // h 类型为int            decltype还有一些值得注意的地方,我们先来看看下面这段代码: int i = 42, *p = &i, &r = i; decltype(i) x1 = 0; //因为 i 为 int ,所以 x1 为int
auto x2 = i; //因为 i 为 int ,所以 x2 为int decltype(r) y1 = i; //因为 r 为 int& ,所以 y1 为int&
auto y2 = r; //因为 r 为 int& ,但auto会忽略引用,所以 y2 为int decltype(r + 0) z1 = 0; //因为 r + 0 为 int ,所以 z1 为int,
auto z2 = r + 0; //因为 r + 0 为 int ,所以 z2 为int, decltype(*p) h1 = i; //这里 h1 是int&, 原因后面讲
auto h2 = *p; // h2 为 int.            如果表达式的内容是解引用操作,则decltype将得到引用类型。正如我们所熟悉的那样,解引用指针可以得到指针所指对象,而且还可以给这个对象赋值。因此decltype(*p)的结果类型就是int&.
           decltype和auto还有一处重要的区别是,decltype的结果类型与表达形式密切相关。有一种情况需要特别注意:对于decltype 所用表达式来说,如果变量名加上一对括号,则得到的类型与不加上括号的时候可能不同。如果decltype使用的是一个不加括号的变量,那么得到的结果就是这个变量的类型。但是如果给这个变量加上一个或多层括号,那么编译器会把这个变量当作一个表达式看待,变量是一个可以作为左值的特殊表达式,所以这样的decltype就会返回引用类型: int i = 42; //decltype(i) int 类型
//decltype((i)) int& 类型            这里再指出一个需要注意的地方就是 = 赋值运算符返回的是左值的引用。换句话意思就是说 decltype(i = b)  返回类型为 i 类型的引用。仔细看下面这段代码: int main()
{
int i = 42; decltype(i = 41) x = i; auto y = i; auto& z = i; printf("i x y z 此时为: %d %d %d %d\n", i,x,y,z); i--; printf("i x y z 此时为: %d %d %d %d\n", i, x, y, z); x--; printf("i x y z 此时为: %d %d %d %d\n", i, x, y, z); y--; printf("i x y z 此时为: %d %d %d %d\n", i, x, y, z); z--; printf("i x y z 此时为: %d %d %d %d\n", i, x, y, z); return 0;
} 运行结果为:
i x y z 此时为: 42 42 42 42
i x y z 此时为: 41 41 42 41
i x y z 此时为: 40 40 42 40
i x y z 此时为: 40 40 41 40
i x y z 此时为: 39 39 41 39      
           由上面的代码和运行结果可以看出来,1.decltype(i = 41)中的赋值语句并没有真正的运行。2. decltype(i = 41)返回的其实是int&,也就是说x 其实是 i 的引用。 了解了auto 和 decltype后,以后在使用的过程中一定要分清两者的区别,防止在定义的时候产生const 与非const 以及引用 与非引用 的差别!!

C++11新特性— auto 和 decltype 区别和联系的更多相关文章

  1. 【C++11】新特性——auto的使用

    [C++11]新特性——auto的使用 C++11中引入的auto主要有两种用途:自动类型推断和返回值占位.auto在C++98中的标识临时变量的语义,由于使用极少且多余,在C++11中已被删除.前后 ...

  2. [转载] C++11新特性

    C++11标准发布已有一段时间了, 维基百科上有对C++11新标准的变化和C++11新特性介绍的文章. 我是一名C++程序员,非常想了解一下C++11. 英文版的维基百科看起来非常费劲,而中文版维基百 ...

  3. 在C++98基础上学习C++11新特性

    自己一直用的是C++98规范来编程,对于C++11只闻其名却没用过其特性.近期因为工作的需要,需要掌握C++11的一些特性,所以查阅了一些C++11资料.因为自己有C++98的基础,所以从C++98过 ...

  4. C++11新特性总结 (二)

    1. 范围for语句 C++11 引入了一种更为简单的for语句,这种for语句可以很方便的遍历容器或其他序列的所有元素 vector<int> vec = {1,2,3,4,5,6}; ...

  5. C++11新特性总结 (一)

    1. 概述 最近在看C++ Primer5 刚好看到一半,总结一下C++11里面确实加了很多新东西,如果没有任何了解,别说自己写了,看别人写的代码估计都会有些吃力.C++ Primer5是学习C++1 ...

  6. C++11 新特性之智能指针(shared_ptr, unique_ptr, weak_ptr)

    这是C++11新特性介绍的第五部分,涉及到智能指针的相关内容(shared_ptr, unique_ptr, weak_ptr). shared_ptr shared_ptr 基本用法 shared_ ...

  7. c++11新特性注意点

    本文记录下一些c++11新特性需要注意的方面,供日后参考 一.auto auto可以当成“占位符”,根据右边的类型自动推导出变量的类型.需要注意的是 auto不能解决溢出的问题. auto可以与指针和 ...

  8. c++ 11 线程池---完全使用c++ 11新特性

    前言: 目前网上的c++线程池资源多是使用老版本或者使用系统接口实现,使用c++ 11新特性的不多,最近研究了一下,实现一个简单版本,可实现任意任意参数函数的调用以及获得返回值. 0 前置知识 首先介 ...

  9. C++ 11 新特性

    C++11新特性:          1.auto          2.nullptr          3.for          4.lambda表达式          5.override ...

随机推荐

  1. 解决windows下合上、掀开笔记本盖子后屏幕黑屏的问题

    我在macbook上安装了windows10,但是由于驱动问题,虽然我设置的是关闭盖子仅息屏,但是在关闭盖子后一段时间,再掀开,屏幕就怎么样都唤不醒了. 我找到一个方法,虽然治标不治本,但是起码能解决 ...

  2. 攻防世界WEB高手进阶之Zhuanxv

    1.一开始就是一个时钟界面 2.扫描目录发现/list 目录 打开是后台登陆,看了一下源码,也没发现什么,焦灼... 3.百度上搜了一波wp,发现原来在css里面藏了东西 后台的背景图片居然是这样读取 ...

  3. Alpha2的项目互评互测

    目录 @(Alpha2项目测试) 这个作业属于哪个课程 课程链接 这个作业要求在哪里 作业要求的链接 团队名称 你的代码我的发 这个作业的目标 其他参考文献 软件测试用例 姓名 学号 团队名称 李涵 ...

  4. python笔记42-http请求命令行工具(httpie)

    前言 通常我们需要快速的测试某个接口通不通,一般linux上用curl去发http请求,但是这个命令行工具语法有点复杂了,不够直观. python有一个给人类使用的requests库,非常的简单方便. ...

  5. python的any()函数

    any()函数的参数是一个可迭代对象,其中的一个元素有一个为真,则any()函数返回真,除非全部为假的时候才返回假. aaa=[,,,] print(any(aaa)) 返回:false

  6. BZOJ 1034: [ZJOI2008]泡泡堂BNB 贪心+排序

    比较神奇的贪心 有点类似于田忌赛马. 如果我方最弱强于对面最弱,则直接最弱pk最弱. 如果我方最强强于对面最强,那么直接最强间pk. 否则,试着用我方最弱 pk 对方最强,看是否能打成平手. code ...

  7. BZOJ 1758: [Wc2010]重建计划 01分数规划+点分治+单调队列

    code: #include <bits/stdc++.h> using namespace std; #define setIO(s) freopen(s".in", ...

  8. 计蒜客 39268.Tasks-签到 (The 2019 ACM-ICPC China Shannxi Provincial Programming Contest A.) 2019ICPC西安邀请赛现场赛重现赛

    Tasks It's too late now, but you still have too much work to do. There are nn tasks on your list. Th ...

  9. Android入门教程(五)

    关注我,每天都有优质技术文章推送,工作,学习累了的时候放松一下自己. 欢迎大家关注我的微信公众号:「醉翁猫咪」 字面量: 1.整数字面量为整型(int) 2.小数字面量为双精度浮点型(double) ...

  10. C博客作业--我的第一篇博客作业

    1你对网络专业或计算机专业了解是怎样的 由于从小就与电脑打交道,对于各类软件的生产非常感兴趣,所以在高三开学查询有什么专业的时候,就打算报与计算机有关的专业.我对计算机专业感到非常神奇,毕竟只是看似简 ...