C++ 中 auto 与 decltype 的用法与区别
最近在恶补 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
注:decltype()括号中的表达式并不去执行,而 decltype((variable)) 的结果永远是引用,而 decltype((variable)) 只有当 variable 本身是一个引用是才是引用。
auto 关键字和 decltype 关键字的区别
对于 decltype 所用的表达式来说,如果变量名加上一对括号,则得到的类型与不加上括号的时候可能不同。
如果 decltype 使用的是一个不加括号的变量,那么得到的结果就是这个变量的类型。但是如果给这个变量加上一个或多层括号,那么编译器会把这个变量当作一个表达式看待,变量是一个可以作为左值的特殊表达式,所以这样的decltype就会返回引用类型。
如:
int i;
decltype(i) // int类型
decltype((i)) // int& 类型
在这里我们不探讨太多的一些具体的细节,只介绍一些常用的一些用法和注意事项,想了解更多的话参考 C++ Primer Plus 。
作 者:Angel_Kitty
出 处:https://www.cnblogs.com/ECJTUACM-873284962/
关于作者:阿里云ACE,目前主要研究方向是Web安全漏洞以及反序列化。如有问题或建议,请多多赐教!
版权声明:本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接。
特此声明:所有评论和私信都会在第一时间回复。也欢迎园子的大大们指正错误,共同进步。或者直接私信我
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是作者坚持原创和持续写作的最大动力!
欢迎大家关注我的微信公众号IT老实人(IThonest),如果您觉得文章对您有很大的帮助,您可以考虑赏博主一杯咖啡以资鼓励,您的肯定将是我最大的动力。thx.
我的公众号是IT老实人(IThonest),一个有故事的公众号,欢迎大家来这里讨论,共同进步,不断学习才能不断进步。扫下面的二维码或者收藏下面的二维码关注吧(长按下面的二维码图片、并选择识别图中的二维码),个人QQ和微信的二维码也已给出,扫描下面👇的二维码一起来讨论吧!!!
欢迎大家关注我的Github,一些文章的备份和平常做的一些项目会存放在这里。