20170911_decltype和auto的区别

20170911_decltype和auto的区别


顶层const  和 底层const:

指针本身是一个对象,它又可以指向另外一个对象,因此,指针本身是不是常量、以及指针所指的对象是不是一个常量 就是两个相互独立的问题。

1、 顶层const 来描述 指针本身是一个常量,即指针常量。

2、 底层const 来描述 指针所指的对象是一个常量,即常量指针。

(这两个概念,就是指针常量常量指针的区别。

 参考博客:    20170911_指针常量和常量指针的区别以及const和define的区别  )

decltype 类型说明符 的说明:

1、问题引出:

有时会遇到这种情况需要从表达式的类型来推断出要定义的变量的类型,但是不想用该表达式的值来初始化该变量。

为了满足这种需求,C++11 新标准引入了 decltype 类型说明符,在此次过程中,编译器会分析表达式并且得到表达式的类型,却不实际计算表达式的值。

比如:decltype(fun( ))  sum =x;        sum 的类型是函数fun() 的返回值类型。

解释:编译器并不实际调用该函数fun(),而是使用 假设当调用函数fun() 的时候,它的返回值类型就作为 sum 的类型。

2、decltype 处理顶层const 和底层const 的时候:

const int ci = 0,  &cj = ci;        ci 是一个常量变量,cj 是一个常量变量的引用。

decltype( ci )  x = 0;                x 的类型:const int 类型

decltype( cj )  y = x;                y 的类型:const int & 类型,并且绑定到变量x 上。

decltype( cj )  z;                      z 的类型 const int & 类型,因此它必须初始化,但是 z 没有初始化,所有出错!

解释:cj 是一个引用,decltype( cj ) 的结果就是引用类型,因此作为引用类型的z 必须被初始化。

3、decltype 和引用:

如果 decltype 使用的表达式不是一个变量,则 decltype 返回的是表达式对应的类型。

decltype 的结果可以是引用类型。

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

decltype( r+0 ) b;   正确。

decltype( *p )  c;    错误。

解释1:  r 是一个引用,因此 decltype( r ) 的结果是一个引用类型,必须得被初始化。如果想让decltype 的返回类型是 r 所指向的类型,可以把 r 作为表达式的一部分,如 r+0显然这个表达式 decltype( r+0 ) 的结果类型是 int 型而不是一个int 引用类型。

解释2:  如果表达式的内容是一个解引用操作 如 *p,则decltype 的返回值类型是引用类型。正如我们熟悉的那样,解引用指针可以得到指针所指的对象,而且还可以给这个对象赋值。因此,decltype( *p ) 的结果是 int & 类型,而不是int 类型!

4、decltype 和 auto 的一个重要区别:

对于decltype 所用的表达式来说,如果变量名加上了一对括号(),则得到的类型与不加括号时不一样。

如果decltype 使用的是一个不加括号的变量,则得到的结果就是该变量的类型。

如果decltype 使用的是一个加了一层或者多层括号的变量,则编译器会把它当成是一个表达式。变量是一种可以被赋值的左值表达式,因此 这样的 decltype 就会得到 引用类型。

int i = 42, j = 50;

decltype(( i )) d;              decltype 的表达式是加了括号的变量,所以得到的是引用,必须得被初始化。因此,这句话出错!!!

decltype(( i )) d2 = &j;     decltype 的表达式是加了括号的变量,所以得到的是引用,必须得被初始化。正确。

decltype( i ) d3;              decltype 的表达式是没有加括号的变量,所以得到的是该变量的类型,所以 d3 是一个未被初始化的变量


auto 类型说明符的说明:

1、C++11新标准引入了auto 类型说明符,用它就能让编译器替我们去分析表达式所属的类型,auto 是编译器通过初始值来推断变量的类型的。显然,使用auto定义变量 时,必须要有初始值!

使用auto 也能在一条语句中声明多个变量,但是这些变量一定要是同类型的,否则出错!

auto i = 0,  j=1.1;           i 和 j 不是同类型,出错。

auto i = 0,  *p = &i;        i 是整型,p 是整型指针,正确。  

2、使用引用,其实使用的是引用的对象,特别是当引用被用作初始值的时候,真正参与初始化的其实是引用对象的值,因此,编译器是使用引用对象的类型来作为auto 的类型。

int i = 0, &r = i;

auto a = r;         正确,a 的类型是r 做引用的变量的类型,即 int 类型。

另外,auto 会去除掉顶层const 属性,同时,底层const 属性会保留下来。

const int ci = i, &cr = ci;

auto b = ci;                    b 是一个整数,ci 的顶层const 属性被忽略掉。

auto c = cr;                   c 是一个整数,cr 是 ci 的别名,ci 本身是一个顶层 const。

auto d = &i;                   d 是一个整型指针,整数的地址就是指向整数的指针。

auto e = &ci;                 e 是一个指向整数常量的指针。






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值