有auto为什么还要decltype ?详解decltype的用法[通俗易懂]

有auto为什么还要decltype ?详解decltype的用法[通俗易懂]decltype用法auto和decltype推导类型的区别decltype用法:1.decltype变量2.==decltype表达式==2.1表达式做右值2.2表达式能做左值3.decltype函数3.1decltype(f())3.2decltype(f)C++11中decltype的主要作用auto和decltype推导类型的区别在中,我介绍了auto的用法及其实际编程中的应用,既然auto可以推导变量的类型,为什么C++11还引进decltype类型说明符呢?关于这一点,C++

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

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

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的详细介绍。如果有疑问,欢迎评论区下方留言;本人水平有限 ,如有错误,也欢迎在评论区下方批评指正。若是喜欢本文,就帮忙点赞吧

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

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

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


相关推荐

  • elasticsearch系列二:索引详解(快速入门、索引管理、映射详解、索引别名)

    elasticsearch系列二:索引详解(快速入门、索引管理、映射详解、索引别名)

    2022年4月3日
    113
  • navicat15 永久激活码最新_最新在线免费激活

    (navicat15 永久激活码最新)好多小伙伴总是说激活码老是失效,太麻烦,关注/收藏全栈君太难教程,2021永久激活的方法等着你。IntelliJ2021最新激活注册码,破解教程可免费永久激活,亲测有效,下面是详细链接哦~https://javaforall.net/100143.html1STL5S9V8F-eyJsaWNlbnNlSW…

    2022年3月27日
    60
  • 服务器防御DDoS的方法,一文解决DDoS攻击

    服务器防御DDoS的方法,一文解决DDoS攻击近来,DDoS攻击越来越严重,香奈儿韩国分公司在黑客入侵其数据库后发表了道歉声明,表示公司已封锁黑客攻击背后的IP地址,并聘请一家网络安全公司调查此事。广大的网站用户应该采取怎样的措施进行有效的防御呢

    2022年7月1日
    20
  • 屏蔽(禁止)鼠标右键代码「建议收藏」

    屏蔽(禁止)鼠标右键代码「建议收藏」屏蔽鼠标右键禁止鼠标右键onselectstart="returnfalse"禁止选择,ondragstart="returnfalse"禁止拖放,o

    2022年7月3日
    16
  • Ubuntu 更换国内源[通俗易懂]

    Ubuntu 更换国内源[通俗易懂]Ubuntu系统自带的源都是国外的网址,国内用户在使用的时候网速比较慢。一个软件的下载是十分痛苦的,这里讲解一下如何将国外源更换为国内源,让你的网速Biu.Biu.Biu1.备份原来的源sudocp/etc/apt/sources.list/etc/apt/sources_init.list将以前的源备份一下,以防以后可以用的。2.更换源sudogedi…

    2022年5月4日
    37
  • linux 驱动移植_免驱动led灯好吗

    linux 驱动移植_免驱动led灯好吗通过前两篇文章的介绍,我们已经把linux内核移植到了tiny210上,但是看到的现象都是通过超级终端来观察的,下面了,我们介绍一下led灯的移植,给大家一个更直观的感受。这篇文章主要的内容如下:1.对平台总线的简介;2.led驱动的移植。一.平台总线   首先介绍一下,我们为什么要简单介绍一下平台总线呢?因为我们是做led驱动的移植,而不是自己编写led的驱动代码。我们要移植

    2022年9月25日
    0

发表回复

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

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