前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >C++ 中 auto 与 decltype 的用法与区别

C++ 中 auto 与 decltype 的用法与区别

作者头像
Angel_Kitty
发布2019-05-07 14:34:00
2K0
发布2019-05-07 14:34:00
举报

最近在恶补 C++ 知识的时候,学习到了一些 C++11 标准的新特性,利用这些新特性,我们能够更快地提高编程效率,从而实现我们的目标,在此特意记下学习过程中所学习到的一些东西,方便日后的回顾和复习。

auto 关键字

在我们日常编程的时候,我们常常需要把表达式的值赋给变量,需要在声明变量的时候,我们必须清楚的知道变量是属于什么类型的。然而往往有些时候,我们做到这一点并非易事。为了解决这个问题, C++11 新标准就引入了 auto 类型说明符,通过使用 auto 关键字,我们就能让编译器替我们去分析表达式所属的类型,和原来那些只对应某种特定的类型说明符(例如 int )不同, auto 能让编译器通过初始值来进行类型推演,从而获得定义变量的类型,这样一来,我们就可以大大地降低我们在编程中出现变量类型错误的概率了。

需要注意的一点⚠️:auto 定义的变量必须有初始值。

举个例子:

代码语言:javascript
复制
#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;
}

运行结果如下:

代码语言:javascript
复制
value1 的类型是 i
value2 的类型是 d
value3 的类型是 c

注: typeid() 操作符可以输出变量的类型,其库函数在 头文件中,如上面?这个例子所示。

编译器推断出来的 auto 类型有时候会跟初始值的类型并不完全一样,编译器会适当的改变结果类型,使得其更符合初始化规则。例如我们平常用的浮点数类型 float 和 double ,编译器似乎会优先选择 double 类型。

但 auto 需要注意的一点就是,使用 auto 能在一个语句中声明多个变量,但是一个语句在声明多个变量的时候,只能有一个基本数据类型,所以该语句中所有变量的初始基本数据类型都必须是一样的。在这里一定要区别数据类型和类型修饰符!!

例如:

我们在上面代码中增加 value4 和 value5:

代码语言:javascript
复制
auto value4 = "QAQ", value5 = &value1;

我们可以看到,在编译时出现了报错,原因是因为 value4 推断出的类型是字符串型,而 value5 推断出来的类型是指针类型,一条语句在声明多个变量的时候,只能有一个基本数据类型,所以会有如下的错误出现。

decltype 关键字

而 decltype 类型说明符也是 C++11 的标准,它是用于从表达式的类型推断出要定义的变量的类型。

因为在有些时候,我们会遇到如下这种情况:

我们希望从表达式中推断出要定义变量的类型,但却不想用表达式的值去初始化变量,或者当函数的返回值类型为某表达式的值的类型,这个时候, auto 显得就很无力了,所以 C++11 又引入了第二种类型说明符 decltype 。它的作用是选择并返回操作数的数据类型。在此过程中,编译器只是分析表达式或函数的返回值的类型并得到它的类型,却不进行实际的计算表达式的值。

举个例子:

代码语言:javascript
复制
#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;
}

输出结果如下:

代码语言:javascript
复制
a 的类型是 NSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEE
b 的类型是 i

注:decltype()括号中的表达式并不去执行,而 decltype((variable)) 的结果永远是引用,而 decltype((variable)) 只有当 variable 本身是一个引用是才是引用。

auto 关键字和 decltype 关键字的区别

对于 decltype 所用的表达式来说,如果变量名加上一对括号,则得到的类型与不加上括号的时候可能不同。

如果 decltype 使用的是一个不加括号的变量,那么得到的结果就是这个变量的类型。但是如果给这个变量加上一个或多层括号,那么编译器会把这个变量当作一个表达式看待,变量是一个可以作为左值的特殊表达式,所以这样的decltype就会返回引用类型。

如:

代码语言:javascript
复制
int i;
decltype(i) // int类型
decltype((i)) // int& 类型

在这里我们不探讨太多的一些具体的细节,只介绍一些常用的一些用法和注意事项,想了解更多的话参考 C++ Primer Plus 。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019-04-21 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • auto 关键字
  • decltype 关键字
  • auto 关键字和 decltype 关键字的区别
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档