【C++】C++11标准新关键字auto、decltype

复合类型

复合类型是基于其他类型定义的类型。

顶层const、底层const

顶层const表示任意的对象是常量,顶层const是附加在变量名上的属性;

底层const与一些复合类型(如指针)的基本类型部分有关,底层const表示复合类型对象的基本类型部分是常量。

匿名变量的基本属性

通过变量名使用变量的确会把变量名自身的一部分属性附加到变量上,但匿名的变量仍然拥有自己的属性,典型的匿名变量属性有:

  • 左值 / 右值属性
  • 类型属性(int、long、double、复合类型等)

匿名变量也可能是引用…

这是需要特别注意的一点,典型的例子是函数返回引用。请看代码:

int A = 20;

int &test()
{
    return A;
}

int &b = test();	//函数调用表达式表示一个匿名变量,这个匿名变量是函数的返回值,是一个引用

auto类型说明符

编程时常常需要把表达式的值赋给变量,这就要求在声明变量的时候清楚地知道表达式的类型。C++11新标准引入了auto类型说明符,用它就能让编译器替我们去分析表达式所属的类型,再确定所声明的变量名的类型。

显然,用auto定义的变量必须要初始化。

auto类型说明符并不难理解,关键是要明白:编译器通过确定初始值的类型,根据初始化规则,推断出所声明的变量名的类型。但仍有两点需要特别注意:

  • 如果初始值具有顶层const属性,根据初始化规则,所声明的变量名无需具有顶层const属性,因此推断出来的声明类型为非const
  • 如果声明的是引用,由于引用的属性需要推断,这时候引用的左值 / 右值属性是不定的,利用引用折叠规则可以自由转换所声明的引用的左 / 右值属性,而这取决于用于初始化的变量是左值变量还是右值变量
  • 引用折叠规则不是万能的,如果引用折叠规则不能使初始化合法,那么就会产生错误

decltype类型指示符

接着考虑另一种情况:希望从表达式的类型推断出要声明的变量的类型,但是不想用该表达式的值初始化变量。为了满足这一要求,C++11新标准引入了第二种类型说明符decltype,它的作用是判断并返回操作数的数据类型。在此过程中,编译器分析表达式并得到它的类型,却不实际计算表达式的值。

与auto类型说明符不同的是,decltype完全保留变量的属性,包括顶层const属性。当然,除非操作数是引用,否则decltype不会返回左值 / 右值属性。

最特殊的一点是,decltype对待引用时并不把引用看作所绑定的变量,相反,如果操作数时引用,decltype会返回引用的全部属性,包括左值引用 / 右值引用属性。decltype对待引用的方式在以下几点体现得尤为明显:

  • 引用折叠规则

既然decltype返回引用的属性,那么不可避免地会产生 “引用的引用”,这种情况通过引用折叠规则可以得到很好的解决。

  • 解引用指针

解引用表达式的结果是左值引用。这意味着如果decltype的操作数是解引用表达式,那么将会返回引用类型。请看代码:

int a = 10;
int *p = &a;
decltype(*p) c;	//错误,这条语句等价于 int &c,c是int类型的左值引用,必须初始化
  • 双层括号

对于变量名,decltype认为变量名表示变量名所绑定的变量,将会返回这个变量的所有属性(除左值 / 右值属性外)(包括变量名给变量附加的属性);

如果变量名外加了括号,那么decltype认为带括号的变量名表示一个左值引用,这个左值引用具有和变量名相同的属性,这时decltype将会返回引用类型。

请看代码:

int i = 0;
decltype(i) a;		// 等价于 int a;
decltype((i)) b;	// 等价于 int &b;	//错误,b是一个左值引用,必须初始化
发布了19 篇原创文章 · 获赞 23 · 访问量 3894

猜你喜欢

转载自blog.csdn.net/weixin_43737206/article/details/103514223
今日推荐