Decltype 类型指示符

“引用从来都作为其所指对象的同义词出现,只有用在decltype处是一个例外”

理解:

Decltype和auto区别:

1.     auto是从表达式类型推断出要定义的变量类型(这里的表达式是auto声明语句里的右值表达式),且用该表达式的值去初始化。而decltype虽然也是从表达式类型推断要定义的变量类型,但是不会用该表达式的值去初始化(这里的表达式是左值表达式?)

2.     decltype的结果类型与表达式形式密切相关(表达式只有变量和表达式不止有变量)

第二点就是理解这里的关键,对于decltype来说,如果表达式是变量名加上括号得到的就是一个引用(加括号的时候编译器将其视为表达式而不是变量):

int i=0;

decltype((i))d;  //d是一个int引用,必须初始化

decltype(i)d;    //d是一个普通的int

因此对于:

Decltype(*p)c    //c是一个int&,即引用。

在这里,引用和*p联系到了一起,这就是那个例外。

那么,为什么会是这样呢?

此外,为什么变量加个括号,在decltype中就会返回引用类型呢?

这一切都和区别2和左右值在decltype中的应用有关。

首先我们要明确,decltype中,表达式只有变量不会出现这种差异,变量是什么就返回什么;只有在表达式不止是变量时会有不同。

表达式之所以不同,是因为decltype此时是根据表达式的结果来返回对应的类型.那么表达式的结果有哪些呢?

1.表达式的结果对象能作为一条赋值语句的左值时,decltype返回的是引用类型

想到这,有必要再次深入了解C++中的左右值区别了。之前存的文章:

https://stackoverflow.com/questions/3601602/what-are-rvalues-lvalues-xvalues-glvalues-and-prvalues

以及最近在看的网络课笔记:

http://www.cnblogs.com/wuduojia/articles/7635635.html

派上了用场,接下来就是自己试着合起来理解一下。

首先是stack overflow里高票答案的理解:

一切的原因可能是因为移动时全语义的变化(全语义的意思见网络课笔记)。一旦我们对表达式进行移动而非复制,很容易就能看出在不同表达式上移动的区别。根据我对草案的理解,我认为rvalue和lvalue的概念和以前一样,只是在移动时更加细分了这个概念。

为什么需要它?也许并不是我们想的那样即定义不一样了,而是定义的更加精确了而已。

1.lvalue=left value=左值

2.xvalue =expiring value=消亡值

3.glvalue =generalized lvalue=泛左值

4.rvalue=right value=右值

5.prvalue =pure rvalue=纯右值

由于英语差,感觉自己理解的这五种值不对,又去查了资料:

https://www.zhihu.com/question/22111546

https://www.2cto.com/kf/201602/489942.html

https://www.zhihu.com/question/39846131

发现这些答案应该可以说清楚了,但是很多基础性的东西还不懂,无法理解!所以决定先放一放,以后再回头理解!

暂时先按照这篇文章的理解:

http://www.cnblogs.com/wuchanming/p/3751847.html

“使用关键字decltype的时候,左值和右值也有所不同。如果表达式的求值结果是左值,decltype作用于该表达式(不是变量)得到一个引用类型。举个例子,假定p的类型是int* ,因为解引用运算符生成左值,所以decltype(*p)的结果是int&。另一方面,因为解地址运算符生成右值,所以decltype(&p)的结果是int**,也就是说,结果是一个指向整型指针的指针;赋值也会产生引用,引用的类型就是左值的类型:

int a = 3, b = 4;

decltype(a = b)d = a;              //d是int&

即暂时理解为对象是左值,值是右值。当表达式返回的值是左值给decltype时得出的结果是引用。

所以:

int i=42;*p=&i;&r=i;

decltype (r+0)b;    //r+0的结果是一个具体值42,是一个右值,所以返回给decltype的类型是int

decltype(*p)c;       //*p是解引用p,得到的是一个对象,所以返回给decltype的类型是int引用

最新文章

  1. 红米3 TWRP-3.0.2(android_6.0.1_r72分支)中文版Recovery更新于20161018
  2. $(this)在ajax中无效的解决方案
  3. linux手动或者自动启动oracle11g的服务 Oracle 自动启动脚本
  4. osg绘制一个球体
  5. Mongo中append方法使用
  6. 现在写 PHP,你应该知道这些
  7. 什么是javascript-SourceMap
  8. Intel格式和AT&T格式汇编区别
  9. JSON2 源代码
  10. extern “C”的作用
  11. navigaitonBar的自定义设置
  12. Testing a Redux & React web application
  13. [BZOJ 1500]维修数列 [Splay Tree从进阶到住院]
  14. UOJ400/LOJ2553 CTSC2018 暴力写挂 边分治、虚树
  15. 没啥事用C语言写一个Trie tree玩玩,支持中英文,用g++编译通过
  16. SCRUM 12.03
  17. Python 递归删除非空目录(包括子目录以及文件)
  18. python 多线程与GIL
  19. iOS UI-popoverController
  20. HDFS元数据管理机制

热门文章

  1. C#——await与async实现多线程异步编程
  2. Codeforces Round #271 (Div. 2) D. Flowers (递推 预处理)
  3. yarn 和 npm 的区别
  4. Objective-C语言的 if ( self = [super init] )
  5. 用js采集网页数据并插入数据库最快的方法
  6. 说说循环与闭包——《你不知道的JS》读书笔记(一)
  7. where 1=1影响效率以及having和where的区别
  8. web filter用spring注入对象
  9. xUnit随笔
  10. [bzoj3073]Journeys