C++关键字decltype

news/2024/7/3 0:23:43

1. decltype简介

decltype与auto关键字一样,用于进行编译时类型推导,不过它与auto还是有一些区别的。decltype的类型推导并不是像auto一样是从变量声明的初始化表达式获得变量的类型,而是总是以一个普通表达式作为参数,返回该表达式的类型,而且decltype并不会对表达式进行求值。

2. 推导规则

decltype的推导规则可以简单概述如下:

如果exp是一个不被括号()包围的表达式,或者是一个类成员访问表达式,或者是一个单独的变量,decltype(exp)的类型和exp一致
如果exp是函数调用,则decltype(exp)的类型就和函数返回值的类型一致
如果exp是一个左值,或被括号()包围,decltype(exp)的类型就是exp的引用,假设exp的类型为T,则decltype(exp)的类型为T&

struct A { double x; 
};const A* a = new A{0};

第一种情况 

decltype(a->x) y;       // type of y is double
decltype((a->x)) z = y; // type of z is const double&,因为a一个常量对象指针

第二种情况

int* aa=new int;
decltype(*aa) y=*aa;    //type of y is int&,解引用操作

第三种情况 

decltype(5) y;          //type of y is int
decltype((5)) y;        //type of y is int
const int&& RvalRef() { return 1; }
decltype ((RvalRef())) var = 1;  //type of var is const int&&

与using/typedef合用,用于定义类型。

using size_t = decltype(sizeof(0));//sizeof(a)的返回值为size_t类型
using ptrdiff_t = decltype((int*)0 - (int*)0);
using nullptr_t = decltype(nullptr);vector<int>vec;
typedef decltype(vec.begin()) vectype;
for (vectype i = vec.begin; i != vec.end(); i++){...}

显而易见,与auto一样,也提高了代码的可读性。 

重用匿名类型。在 C++ 中,我们有时候会遇上一些匿名类型。 

struct {int d ;double b;
} anon_s;

 借助 decltype,我们可以重新使用这个匿名的结构体,C++11 之前我们是无法做到的。

decltype(anon_s) as; //定义了一个上面匿名的结构体

 注意,匿名类型有其匿名的原因,一般情况下,匿名类型不应该被重用,应尽量避免这种用法。
泛型编程中结合 auto,用于追踪函数的返回值类型,这是 decltype的最大用途。decltype 帮助 C++ 模板更加泛化,程序员在编写代码时无需关心任何时段的类型选择,编译器会合理地进行推导。

template <typename _Tx, typename _Ty> auto multiply(_Tx x, _Ty y)->decltype(x*y) { return x*y; 
}

参考文献

【C++】C++11新增关键字详解_郭老二的博客-CSDN博客_c++11关键字

C++ decltype用法详解_qq_38196982的博客-CSDN博客_c++ decltype 

c++ 关键字 decltype_时光在身后挡住去路的博客-CSDN博客 


http://lihuaxi.xjx100.cn/news/246283.html

相关文章

求几亿个数中不重复元素的个数

题目&#xff1a; 有2.5亿个无符号整数&#xff08;但在文件里面&#xff09;&#xff0c;要求找出这2.5亿个数字里面&#xff0c;不重复的数字的个数&#xff08;那些只出现一次的数字的数目&#xff09;&#xff1b;另外&#xff0c;可用的内存限定为600M&#xff1b;要求算法…

android sqlite操作(2)

以下只是我个人的浅见,大神请忽略~ 这一篇说一下sqlite的相关操作,其实安卓提供了相当多的操作sqlite的方法,这里我介绍下我常用的方法。 (1)创建一个数据库文件,这个很简单 1 File dbPathFile new File(dbPath); 2 if(!dbPathFile.exists()) 3 try { 4 dbPathFil…

C++关键字const与constexpr

1. const 1.1. 修饰一般常量 一般常量是指简单类型的常量。这种常量在定义时&#xff0c;修饰符const可以用在类型说明符前&#xff0c;也可以用在类型说明符后。 例如&#xff1a; int const x 2; const int y 2; const std::string& name "csdn"; 1.2…

RNN,LSTM,GRU简单图解:

一篇经典的讲解RNN的&#xff0c;大部分网络图都来源于此&#xff1a;http://colah.github.io/posts/2015-08-Understanding-LSTMs/ 每一层每一时刻的输入输出&#xff1a;https://www.cnblogs.com/lovychen/p/9368390.html 带有权重标识的图&#xff1a;

javascript里面RegExp的exec函数的总结

2019独角兽企业重金招聘Python工程师标准>>> 在我们的前端里面&#xff0c;经常会用到正则表达式进行检索字符串&#xff0c;刚好javascript里面提供RegExp来支持正则表达式&#xff0c;而RegExp对象的主要方法是exec()。 语法 RegExpObject.exec(string) 参数 描述…

详解zabbix中文版安装部署

一、zabbix简介&#xff08;摘自百度百科&#xff09;zabbix是一个基于WEB界面的提供分布式系统监视以及网络监视功能的企业级的开源解决方案。zabbix能监视各种网络参数&#xff0c;保证服务器系统的安全运营&#xff1b;并提供柔软的通知机制以让系统管理员快速定位/解决存在…

C++关键字register

这个关键字请求编译器尽可能的将变量存在CPU内部寄存器中&#xff0c;而不是通过内存寻址访问&#xff0c;以提高效率。注意是尽可能&#xff0c;不是绝对。你想想&#xff0c;一个CPU 的寄存器也就那么几个或几十个&#xff0c;你要是定义了很多很多register 变量&#xff0c;…

P4269 [USACO18FEB]Snow Boots G

思维题。 以地板为序构造链表&#xff0c;再排序&#xff0c;然后删除走不过去的地面。 删除的时候顺便维护最大的跨度&#xff0c;以此判断可行性。 总的来说利用了答案的单调性。 #include <cstdio> #include <cstring> #include <iostream> #include <…