旗下导航:搜·么
当前位置:网站首页 > .Net教程 > 正文

C++11新特征中auto 和 decltype 区分和联络【C#.Net教程】,C++11新特性 auto decltype

作者:搜教程发布时间:2019-11-27分类:.Net教程浏览:65评论:0


导读:C++11新特征中auto和decltype区分和联络一.auto简介编程时刻经常须要把表达式的值付给变量,须要在声明变量的时刻清晰的晓得变量是什么范例。然则做...
C++11新特征中auto 和 decltype 区分和联络

一. 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 区分和联络相干文章请关注ki4网!

标签:C++11新特性 auto decltype


欢迎 发表评论: