最近在恶补 C++ 知识的时候,学习到了一些 C++11 标准的新特性,利用这些新特性,我们能够更快地提高编程效率,从而实现我们的目标,在此特意记下学习过程中所学习到的一些东西,方便日后的回顾和复习。
auto 关键字
在我们日常编程的时候,我们常常需要把表达式的值赋给变量,需要在声明变量的时候,我们必须清楚的知道变量是属于什么类型的。然而往往有些时候,我们做到这一点并非易事。为了解决这个问题, C++11 新标准就引入了 auto 类型说明符,通过使用 auto 关键字,我们就能让编译器替我们去分析表达式所属的类型,和原来那些只对应某种特定的类型说明符(例如 int )不同, auto 能让编译器通过初始值来进行类型推演,从而获得定义变量的类型,这样一来,我们就可以大大地降低我们在编程中出现变量类型错误的概率了。
需要注意的一点⚠️:auto 定义的变量必须有初始值。
举个例子:
#include <iostream> #include <typeinfo> using namespace std; int main(int argc, const char *argv[]) { auto value1 = 1; auto value2 = 2.33; auto value3 = 'a'; std::cout << "value1 的类型是 " << typeid(value1).name() << std::endl; std::cout << "value2 的类型是 " << typeid(value2).name() << std::endl; std::cout << "value3 的类型是 " << typeid(value3).name() << std::endl; return 0; }
运行结果如下:
value1 的类型是 i value2 的类型是 d value3 的类型是 c
注: typeid() 操作符可以输出变量的类型,其库函数在 头文件中,如上面👆这个例子所示。
编译器推断出来的 auto 类型有时候会跟初始值的类型并不完全一样,编译器会适当的改变结果类型,使得其更符合初始化规则。例如我们平常用的浮点数类型 float 和 double ,编译器似乎会优先选择 double 类型。
但 auto 需要注意的一点就是,使用 auto 能在一个语句中声明多个变量,但是一个语句在声明多个变量的时候,只能有一个基本数据类型,所以该语句中所有变量的初始基本数据类型都必须是一样的。在这里一定要区别数据类型和类型修饰符!!
例如:
我们在上面代码中增加 value4 和 value5:
auto value4 = "QAQ", value5 = &value1;
我们可以看到,在编译时出现了报错,原因是因为 value4 推断出的类型是字符串型,而 value5 推断出来的类型是指针类型,一条语句在声明多个变量的时候,只能有一个基本数据类型,所以会有如下的错误出现。
decltype 关键字
而 decltype 类型说明符也是 C++11 的标准,它是用于从表达式的类型推断出要定义的变量的类型。
因为在有些时候,我们会遇到如下这种情况:
我们希望从表达式中推断出要定义变量的类型,但却不想用表达式的值去初始化变量,或者当函数的返回值类型为某表达式的值的类型,这个时候, auto 显得就很无力了,所以 C++11 又引入了第二种类型说明符 decltype 。它的作用是选择并返回操作数的数据类型。在此过程中,编译器只是分析表达式或函数的返回值的类型并得到它的类型,却不进行实际的计算表达式的值。
举个例子:
#include <iostream> #include <typeinfo> using namespace std; std::string func(){ return "Hello World!"; } int main(int argc, const char *argv[]) { decltype(func()) a; int i; decltype(i) b; std::cout << "a 的类型是 " << typeid(a).name() << std::endl; std::cout << "b 的类型是 " << typeid(b).name() << std::endl; return 0; }
输出结果如下:
a 的类型是 NSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEE b 的类型是 i C++ 复制 全屏
注:decltype()括号中的表达式并不去执行,而 decltype((variable)) 的结果永远是引用,而 decltype((variable)) 只有当 variable 本身是一个引用是才是引用。
auto 关键字和 decltype 关键字的区别
对于 decltype 所用的表达式来说,如果变量名加上一对括号,则得到的类型与不加上括号的时候可能不同。
如果 decltype 使用的是一个不加括号的变量,那么得到的结果就是这个变量的类型。但是如果给这个变量加上一个或多层括号,那么编译器会把这个变量当作一个表达式看待,变量是一个可以作为左值的特殊表达式,所以这样的decltype就会返回引用类型。
如:
int i; decltype(i) // int类型 decltype((i)) // int& 类型
在这里我们不探讨太多的一些具体的细节,只介绍一些常用的一些用法和注意事项,想了解更多的话参考 C++ Primer Plus 。