有auto为什么还要decltype ?详解decltype的用法
decltype用法
- auto和decltype推导类型的区别
- decltype用法:
- 1.decltype变量
- 2.==decltype表达式==
- 2.1 表达式做右值
- 2.2 表达式能做左值
- 3. decltype 函数
- 3.1 decltype(f())
- 3.2 decltype(f)
- C++ 11 中decltype的主要作用
auto和decltype推导类型的区别
在中,我介绍了auto的用法及其实际编程中的应用,既然auto可以推导变量的类型,为什么C++11还引进decltype类型说明符呢?关于这一点,C++ Primer中这样写道:有时希望从表达式的类型推断出要定义的变量的类型
(这一点auto可以做到),但是不想用该表达式的值初始化变量
(auto依赖这一点才能推导类型)。如果你还是不明白,请开下面的例子:
int a = 10,b = 11;
auto c = a + b; //c为int型
decltype(a + b) d ; //d为int型
auto通过初始化它的表达式来推断c的类型,也就是说,auto推导变量依赖于初始化它的表达式,并且auto声明的变量必须初始;而decltype是直接通过某一个表达式来获取数据类型,从而定义d的类型。
decltype用法:
1.decltype变量
形式:decltype(var)
和auto不同,decltype会保留const属性和引用属性,看下面的例子:
const int ci = 0, &cj = ci;decltype(ci) x = 0;//x的类型为const int
decltype(cj) y = x; //y的类型为const int&
decltype(cj) z; //错误,因为z的类型为const int&,必须初始化auto w = ci;//w的类型是int
w = 9;
auto n = cj;//n的类型是int
2.decltype表达式
形式:decltype(expr)
decltype表达式时,返回的类型根据表达式的结果不同而不同:expr返回左值,得到该类型的左值引用;expr返回右值,得到该类型。
2.1 表达式做右值
如下面的例子中:
尽管r是引用类型,但是r+0是一个具体的值,只能做右值,值对应的类型是int型,所以b为int类型。
int i = 42, &r = i;
decltype(r + 0) b; //b类型是int,而不是int&
2.2 表达式能做左值
结论:表达式能做左值,推导为类型的引用
。
表达式能做左值有两个典型的例子:decltype (*p)和decltype ((ii))
。请看下面的例子:
- 对于解引用*p, 它代表的是p指向地址中的值,同时我们可以给这个值赋值,即为左值。所以,decltype(*p)是int& ,这样才能有给绑定变量的值赋值的特点。
- ii是一个变量,加上括号后变为表达式,即(ii)是一个表达式,又我们可以ii赋值,即为左值。所以,decltype((var))永远是一个引用类型,decltype((ii))声明变量d时,d就为int&类型。
int ii = 42, *p = ⅈdecltype(*p) c;//错误,c是int&,必须初始化decltype((ii)) d;//错误,d是int&,必须初始化
3. decltype 函数
3.1 decltype(f())
直接看下面的例子:
decltype(f()) sum = x;
其中,sum的类型就是函数f的返回类型,sum的类型就是假如函数f被调用,它会返回那个类型。注意:若是函数f的返回值为void,编译报错
。
再看下面的例子:
m的类型为int型;m2的类型为double型。
template <typename T>
T add(T a, T b)
{return a+b;
}decltype(add(1,2)) m = 10; //m的类型是int
decltype(add(1.0,2.0)) m2 = 20; //m2的类型是double
3.2 decltype(f)
看下面的例子,decltype(add_to)直接返回函数类型,所以pf是一个函数指针。
int add_to(int a, int b)
{return a + b;
}decltype(add_to) *pf = add_to; //pf就是一个函数指针,类型为int (int,int)
pf(1,2);
那么可以返回模板函数的函数指针吗?如下,显然是不行的,因为模板函数依赖于参数列表,只根据函数名是无法推断函数类型的,所以说函数指针pf的类型无法确认
。
template <typename T>
T add_to(T a, T b)
{return a + b;
}decltype(add_to) *pf = add_to;
pf(1,2);
和模板函数一样,如果函数是重载的,也无法通过函数名来推断返回的函数类型,那么也无法返回函数指针,如下面的例子中声明pf为函数指针是错误的。
int add_to(int a, int b)
{return a + b;
}
int add_to(int a, int b,int c)
{return a + b +c;
}
decltype(add_to) *pf = add_to;
pf(1,2);
C++ 11 中decltype的主要作用
Decltype在C++11中的主要作用是用于申明返回值类型依赖于其参数类型的模板函数。例子如下:
template <typename _Tx, typename _Ty>
auto multiply(_Tx x, _Ty y)->decltype(x*y)
{return x*y;
}
注意这里的auto并没有做任何类型推断(关于auto的用法:参考C++ auto用法及应用详解),只是用来表明这里使用的是C++11 的拖尾返回类型(trailing return type)语法,也就是函数返回类型将在参数列表之后进行声明
(在"->"之后),优点是可以使用函数参数来声明函数返回类型(如果将返回类型放置于函数之前,这里的参数x和y还没有被声明,因此不能被使用)。
参考:
《C++ Primer 第5版》2.5.3
以上就是decltype的详细介绍。如果有疑问,欢迎评论区下方留言;本人水平有限 ,如有错误,也欢迎在评论区下方批评指正。若是喜欢本文,就帮忙点赞吧
有auto为什么还要decltype ?详解decltype的用法相关推荐
- C++语法学习笔记二十九: 详解decltype含义,decltype主要用途
实例代码 // 详解decltype含义,decltype主要用途#include <iostream> #include <functional> #include < ...
- slf4j log4j logback关系详解和相关用法 【by Sinte-Beuve】
slf4j log4j logback关系详解和相关用法 slf4j log4j logback的关系 The Simple Logging Facade for Java是什么? log4j和log ...
- 【English】 详解 祈使句的用法
[English] 详解 祈使句的用法 祈使句的定义: 定义:用于表达命令.请求.劝告.警告.禁止 等得句子叫做祈使句.祈使句最常用于表达命令, 因此也常称为命令句. 如: Get out of he ...
- cut最后几位 shell_详解Shell cut用法
详解Shell cut用法 cut是以每一行为一个处理对象的,这种机制和sed一样. cut接受三个定位方法: 1)byte: -b 2)characters: -c 3)fields: -d eg: ...
- js中childNodes易错点、详解定义以及用法
js中childNodes易错点.详解定义以及用法 最近学习的时候,我遇到了childNodes的一些问题,我查阅了一些资料,总结一下其定义及用法.在学习childNodes之前,我们需要先了解一下D ...
- vue template html属性,详解template标签用法(含vue中的用法总结)
一.html5中的template标签 html中的template标签中的内容在页面中不会显示.但是在后台查看页面DOM结构存在template标签.这是因为template标签天生不可见,它设置了 ...
- 位运算详解+竞赛常见用法总结
目录 一.位运算详解 二.位运算应用 1.快速幂 2.给定一个数组A, 长度为n,求下面这段程序的值 3.数数字 4.数数字 2 5.nim博弈问题: 6.树状数组 7.判断一个数x是不是2的某次方 ...
- java jar包详解_Jar打包用法详解
这篇文章主要介绍了Jar打包用法,详解分析了jar打包命令的各种常见用法及参数含义,非常具有实用价值,需要的朋友可以参考下 本文较为详细的分析了Jar打包的用法.分享给大家供大家参考.具体分析如下: ...
- JUnit4单元测试、JUnit4使用详解、assertThat用法
2019独角兽企业重金招聘Python工程师标准>>> 一.JUnit基本介绍 1.简介 JUnit是一个开放源码的.Java语言的单元测试框架,用于测试期望结果的断言(Assert ...
最新文章
- day03-字符编码与转换
- 机器学习中的优化算法!
- java学习笔记-set
- 大话数据结构与算法:算法初步1
- 编译性语言、解释性语言和脚本语言的区别
- 全部换新-微软复兴.NET,C#10 .NET6 VS2022各个强势!
- centos oracle sqlplus,centos 下oracle sqlplus乱码问题解决
- bzoj 1643: [Usaco2007 Oct]Bessie's Secret Pasture 贝茜的秘密草坪(DP)
- linux fdisk的分区和格式化和挂载相关操作说明
- 跨域cookie设置
- FreeSwitch视频会议,4路以上CPU占用暴增的原因
- 超级实用且不花哨的js代码大全 (六) ----代码判断,幻灯片播放器,广告效果
- 给大家推荐下这几年看过的觉得不错的视频教程
- FPGA信号截位策略
- linux运维排查常用命令(开发专享)
- ros中的velocity smoother详细分析
- 鼠眼看Linux调度器 by raise_sail @ chinaunix
- OFDM时频脉冲形状与子载波正交性的理解
- ROS2学习笔记(3)什么是ROS2 topics
- 职称计算机考试时的输入法,2017年高级职称计算机预习:输入法的使用