【C++深陷】之“decltype”[通俗易懂]

【C++深陷】之“decltype”[通俗易懂]decltype被称作类型说明符,它的作用是选择并返回操作数的数据类型。随着程序越来越复杂,有时候根本搞不清到底需要什么类型,不得不回过头去从上下文进行推测。decltype可以作用于变量,也可以作用于表达式。


Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

0. decltype关键字

decltype被称作类型说明符,它的作用是选择并返回操作数的数据类型。

// sum的类型就是函数f返回的类型
decltype(f()) sum = x;

回想【C++深陷】之“类型与变量”第4节,我们将定义变量的方法规范为:

类型说明符 声名符列表

decltype就是一种类型说明符,它的出现主要是解决复杂的类型声明。

随着程序越来越复杂,程序中用到的类型也越来越多,这种复杂性体现在两个方面。

一是一些类型难于“拼写”,它们的名字既难记又容易写错,还无法明确体现其真实目的和含义。

二是有时候根本搞不清到底需要的类型是什么,程序员不得不回过头去从程序的上下文寻求帮助。

解决问题一,可以使用类型别名技术。

解决问题二,可以使用auto和本文的主题:decltype。

关于decltype,需要注意:

  1. 工作原理
  2. decltype + 变量 var
  3. decltype + 表达式 expr
  4. decltype + 函数名 func_name

1. 工作原理

decltype并不会实际计算表达式的值,编译器分析表达式并得到它的类型。

函数调用也算一种表达式,因此不必担心在使用decltype时真正的执行了函数,正如前例中的f()。

2. decltype + 变量

根据【C++深陷】之“表达式与运算符”中关于表达式的定义,我们知道单独使用一个变量,相当于一个最简单的表达式。

但是在decltype这里有区别。

①当使用decltype(var)的形式时,decltype会直接返回变量的类型(包括顶层const和引用),不会返回变量作为表达式的类型。

const int ci = 0, &cj = ci;

// x的类型是const int
decltype(ci) x = 0;

// y的类型是const int &
decltype(cj) y = x;

decltype加指针也会返回指针的类型。

decltype加数组,不负责把数组转换成对应的指针,所以其结果仍然是个数组(P206)。

总之decltype(var)完美保留了变量的类型。

“变量作为表达式的类型”是什么呢?见下节。

3. decltype + 表达式

②当使用decltype(expr)的形式时,decltype会返回表达式结果对应的类型。

回想【C++深陷】之“表达式与运算符”,一个表达式的结果不是左值,就是右值。

关于左值和右值,请参考【C++深陷】之“左值与右值”。

因此,decltype(expr)的结果根据expr的结果不同而不同:expr返回左值,得到该类型的左值引用;expr返回右值,得到该类型。

int i = 42, *p = &i, &r = i;

// r + 0是一个表达式
// 算术表达式返回右值
// b是一个int类型
decltype(r + 0) b;

// c是一个int &
decltype(*p) c = i;

这里注意一下decltype(*p)。

解引用运算符*作用于指针类型,得到了p指向的对象的左值(*p = 2很正确),p是指向int的指针,因此decltype(*p)得到的类型是int &。

再来看第2节说到的“变量作为表达式的类型”。

当变量作为表达式时,返回的是该变量的一个左值形式(因为该表达式的结果可以作为赋值语句的左侧的值)。因此,使用decltype理应得到一个该类型的左值引用。

但是decltype单独作用于对象,没有使用对象的表达式的属性,而是直接获得了变量的类型。

要想获得变量作为表达式的类型,可以加一个括号:

int i = 42;

// 加了括号,变成了表达式
// 返回的是i的左值形式
// 因此ri的类型是int &
decltype((i)) ri = i;

那么请问,下面的代码,temp是什么类型:

int i = 42, *p = &i;

decltype((p)) temp = p;

解析:decltype作用的是表达式,(p)得到的是p的左值,所以temp一定是一个引用;p是指向int类型的指针,因此decltype得到的是指向int类型的指针的引用。

4. decltype + 函数

C++中通过函数的返回值和形参列表,定义了一种名为函数类型的东西。它的作用主要是为了定义函数指针。

例如:

// 声明了一个函数类型
using FuncType = int(int &, int);

// 下面的函数就是上面的类型
int add_to(int &des, int ori);

// 声明了一个FuncType类型的指针
// 并使用函数add_to初始化
FuncType *pf = add_to;

int a = 4;

// 通过函数指针调用add_to
pf(a, 2);

我们可以使用decltype获得函数add_to的类型:

decltype(add_to) *pf = add_to;

这样的声明就简单多了。

③当使用decltype(func_name)的形式时,decltype会返回对应的函数类型,不会自动转换成相应的函数指针。

5. 总结

decltype是为了解决复杂的类型声明而使用的关键字,称作decltype类型说明符。

decltype可以作用于变量、表达式及函数名。①作用于变量直接得到变量的类型;②作用于表达式,结果是左值的表达式得到类型的引用,结果是右值的表达式得到类型;③作用于函数名会得到函数类型,不会自动转换成指针。

decltype不会去真的求解表达式的值,可以放心使用。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/195408.html原文链接:https://javaforall.net

赞 (0)
全栈程序员-站长的头像全栈程序员-站长

相关推荐

  • SSR服务器端渲染(Next.js总结和豆瓣电影项目)「建议收藏」

    SSR服务器端渲染(Next.js总结和豆瓣电影项目)「建议收藏」一.前言先解释一下Nuxt.js和Next.js虽然只有一个字母之差,但它们是不同的两个服务端渲染框架.什么是Next.js?引用Next中文官网的一句话:Next.js是一个轻量级的React服务端渲染应用框架。Next.js带来了很多好的特性:默认服务端渲染模式,以文件系统为基础的客户端路由(注意:没有专门路由)代码自动分割使页面加载更快以webpack的热替换(HMR…

    2022年10月31日
  • listView1_ItemSelectionChanged事件

    listView1_ItemSelectionChanged事件ItemSelectionChanged事件会触发2次,其中第1次触发,是listview控件先做取消所有选择,第2次才是选择用户选定的项。所以要加上if(e.IsSelected)来判断是否是用户选择改变时触发。…

    2022年7月26日
  • xps 转 pdf android版,OakDoc XPS to PDF Converter(XPS文件转PDF格式工具)V2.2 正式版

    xps 转 pdf android版,OakDoc XPS to PDF Converter(XPS文件转PDF格式工具)V2.2 正式版OakDocXPStoPDFConverter(XPS文件转PDF格式工具)是一款很优秀好用的XPS转PDF的辅助工具。如果你需要一款好用的文件转换工具,小编带来的这款OakDocXPStoPDFConverter软件是很不错的选择,功能强大全面,使用后可以帮助用户轻松将XPS文件转换成PDF格式。软件可帮助用户通过简单的方式将XPS文件转换输出为PDF为主的主流图片格式。该工具的…

    2022年5月4日
  • linux 权限详解rwx[通俗易懂]

    linux 权限详解rwx[通俗易懂]第2~10个字符当中的每3个为一组,左边三个字符表示所有者权限,中间3个字符表示与所有者同一组的用户的权限,右边3个字符是其他用户的权限。这三个一组共9个字符,代表的意义如下:r(Read,读取):对文件而言,具有读取文件内容的权限;对目录来说,具有浏览目录的权限。w(Write,写入):对文件而言,具有新增、修改文件内容的权限;对目录来说,具有删除、移动目录内文件的权限。x(eXec

    2022年6月1日
  • lstm是rnn中的一种吗_经验公式是什么

    lstm是rnn中的一种吗_经验公式是什么前言好久没用正儿八经地写博客了,csdn居然也有了markdown的编辑器了,最近花了不少时间看RNN以及LSTM的论文,在组内『夜校』分享过了,再在这里总结一下发出来吧,按照我讲解的思路,理解RNN以及LSTM的算法流程并推导一遍应该是没有问题的。RNN最近做出了很多非常漂亮的成果,比如AlexGraves的手写文字生成、名声大振的『根据图片生成描述文字』、输出类似训练语料的文字等应用,都让人感

    2022年8月29日
  • Verizon《市场状况:物联网2017》报告的十大摘要

    Verizon《市场状况:物联网2017》报告的十大摘要

    2022年3月11日

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号