C++11的特性:decltype 类型推导
创始人
2024-05-08 12:18:14
0

文章目录

    • 1、简介
    • 2、decltype 推导规则
      • 2.1 exp 是一个普通表达式
      • 2.2 exp 为函数调用
      • 2.3 exp 是左值,或者被( )包围
    • 3、decltype 与 auto 的区别
      • 3.1 语法的区别
      • 3.2 初始化
      • 3.3 对引用的处理
      • 3.4 对 const 和 volatile 限定符的处理
    • 4、总结
    • 5、参考

1、简介

decltype 是 C++11 新增的一个关键字,它和 auto 的功能一样,都用来在编译时期进行自动类型推导。

decltype 是“declare type”的缩写,译为“声明类型”。

用法:

decltype(exp) varname = value;

varname 表示变量名,value 表示赋给变量的值,exp 表示一个表达式。decltype 根据 exp 表达式推导出变量的类型,跟 = 右边的 value 没有关系。
简而言之,根据 exp 推导类型,根据 value 得到值。

auto 要求变量必须初始化,而 decltype 不要求。

decltype 可以写成下面的形式:

decltype(exp) varname;

2、decltype 推导规则

当程序员使用 decltype(exp) 获取类型时,编译器将根据以下三条规则得出结果:

2.1 exp 是一个普通表达式

如果 exp 是一个不被括号( )包围的表达式,或者是一个类成员访问表达式,或者是一个单独的变量,那么 decltype(exp) 的类型就和 exp 一致,这是最普遍最常见的情况。

int n = 0;
const int &r = n;
Student stu; // Student 是一个类
decltype(n) a = n; // n 为 int 类型,a 被推导为 int 类型
decltype(r) b = n; //r 为 const int& 类型, b 被推导为 const int& 类型
decltype(Student::total) c = 0; //total 为类 Student 的一个 int 类型的成员变量,c 被推导为 int 类型
decltype(stu.name) url = "http://c.biancheng.net/cplus/"; //total 为类 Student 的一个 string 类型的成员变量, url 被推导为 string 类型

2.2 exp 为函数调用

如果 exp 是函数调用,那么 decltype(exp) 的类型就和函数返回值的类型一致。

// 函数声明
int& func_int_r(int, char); // 返回值为 int&
//decltype类型推导
int n = 100;
decltype(func_int_r(100, 'A')) a = n; // a 的类型为 int&

注意,exp 中调用函数时需要带上括号和参数,但这仅仅是形式,并不会真的去执行函数代码。

2.3 exp 是左值,或者被( )包围

如果 exp 是一个左值,或者被括号( )包围,那么 decltype(exp) 的类型就是 exp 的引用;假设 exp 的类型为 T,那么 decltype(exp) 的类型就是 T&。

// 不带括号的表达式
decltype(obj.x) a = 0;  //obj.x 为类的成员访问表达式,符合推导规则一,a 的类型为 int
// 带有括号的表达式
decltype((obj.x)) b = a;  //obj.x 带有括号,符合推导规则三,b 的类型为 int&(引用)//加法表达式
int n = 0, m = 0;
decltype(n + m) c = 0;  // n+m 得到一个右值,符合推导规则一,所以推导结果为 int
decltype(n = n + m) d = c;  // n=n+m 得到一个左值,符号推导规则三,所以推导结果为 int&

重点说一下左值和右值:
左值是指那些在表达式执行结束后依然存在的数据,也就是持久性的数据
右值是指那些在表达式执行结束后不再存在的数据,也就是临时性的数据
有一种很简单的方法来区分左值和右值,对表达式取地址,如果编译器不报错就为左值,否则为右值。

3、decltype 与 auto 的区别

3.1 语法的区别

auto varname = value;  // auto的语法格式
decltype(exp) varname [= value];  // decltype的语法格式

自动推导出变量 varname 的类型的方法不同:

auto 根据=右边的初始值 value 推导出变量的类型;
decltype 根据 exp 表达式推导出变量的类型,跟=右边的 value 没有关系。

3.2 初始化

auto 要求变量必须初始化,也就是在定义变量的同时必须给它赋值;
而 decltype 不要求,初始化与否都不影响变量的类型。
这很容易理解,因为 auto 是根据变量的初始值来推导出变量类型的,如果不初始化,变量的类型也就无法推导了。

3.3 对引用的处理

decltype 会保留引用类型,而 auto 会抛弃引用类型,直接推导出它的原始类型。

int n = 10;
int &r1 = n; // ri 是 int& 类型(是引用类型)// auto推导
auto r2 = r1;// decltype推导
decltype(r1) r3 = n;

在这里, r2 没有指向 n,而是自立门户,单独拥有了一块内存,这就证明 r 不再是引用类型,它的引用类型被 auto 抛弃了。即,修改 r2 的值,不会变动 n 的值。
r3 仍然指向 n,它的引用类型被 decltype 保留了。修改 r3 的值,也会变动 n 的值。

3.4 对 const 和 volatile 限定符的处理

「cv 限定符」是 const 和 volatile 关键字的统称:

  • const 关键字用来表示数据是只读的,也就是不能被修改;
  • volatile 和 const 是相反的,它用来表示数据是可变的、易变的,目的是不让 CPU 将数据缓存到寄存器,而是从原始的内存中读取。

在推导变量类型时,auto 和 decltype 对 cv 限制符的处理是不一样的。
decltype 会保留 cv 限定符,而 auto 有可能 会去掉 cv 限定符。

以下是 auto 关键字对 cv 限定符的推导规则:

  • 如果表达式的类型不是指针或者引用,auto 会把 cv 限定符直接抛弃,推导成 non-const 或者 non-volatile 类型。
  • 如果表达式的类型是指针或者引用,auto 将保留 cv 限定符。

4、总结

auto 虽然在书写格式上比 decltype 简单,但是它的推导规则复杂,有时候会改变表达式的原始类型;
而 decltype 一般会坚持保留原始表达式的任何类型,让推导的结果更加原汁原味。
在实际开发中人们仍然喜欢使用 auto 关键字(我也这么干),因为它用起来简单直观。

5、参考

http://c.biancheng.net/view/7151.html

相关内容

热门资讯

孙杨参赛4项 涵盖短中长距离 转自:天津日报  本报讯(记者 李蓓)昨天,即将在本周末开赛的2025全国游泳冠军赛报项名单出炉。3...
齐鲁品牌文化数智平台共建项目启...   张志恒 王鑫 济南报道  5月13日举行的“新质山东 品筑未来”2025年山东最具影响力品牌暨《...
云湖兰山服务综合体运营 转自:贵州日报 本报讯 5月13日,观山湖区环百花湖旅居推介会暨云湖兰山启幕式在观山湖区朱昌...
守好健康证的“健康关” 人都没到场,证就办好了?近日,有记者走访发现,一些医疗机构的健康证体检项目“缺斤少两”,规章制度形同...
“我的论文不是AI写的”(图) 转自:天津日报  有网友反映,自己原创的论文经过系统检测之后,竟被指出AI生成内容比例过高。据媒体报...
应用机器人与3D打印术行颌骨截...   刘通 通讯员 崔子昂 李鲲济南报道  近日,山东大学齐鲁医院口腔科颌面外科陈安威、王涛、韩亦冰及...
美股周二收盘点评:通货膨胀率下... 来源:宏观对冲陈凯丰Kevin截至4月份的12个月里,消费者物价指数上涨了2.3%,而截至3月份的1...
纽约汇市:美元下跌 美国通胀率...   彭博一项衡量美元强弱的指数兑所有G10货币均走低,此前发布的美国4月份消费者价格涨幅低于预期。投...
要为丘陵山区等研制急需急用的装... □四川日报全媒体记者 阚莹莹  近日,四川省农业农村厅发布2025年“天府良机”薄弱环节关键技术装备...
亮出低空经济发展的未来 □四川日报全媒体记者 高杲 李欣忆7款“四川造”低空产品小鹰-700飞机  ●是目前唯一国产的上单翼...
聆听“沧海龙吟” 共赏民歌之美... 转自:天津日报  本报讯(记者 张帆 摄影 曹彤)昨天,由首都图书馆发起并联合天津图书馆、河北省图书...
彩桥即将合龙   5月12日,宜宾市屏山县岷江二桥工地施工繁忙,建设者对桥梁最后几榀钢拱架进行吊装作业。岷江二桥是...
第二十届西博会5月25日开幕 ●拟邀请匈牙利、老挝为主宾国,浙江、青海为主宾省●拟特邀阿联酋担任大会合作伙伴●据初步统计,西部各地...
各美其美 美美与共 □四川日报全媒体记者 吴晓铃  在古老的历史长河中,留下帕特农神庙、雅典卫城等文明遗产的希腊是西方文...
“公证日记” 转自:天津日报  智慧公证  曾经,办理继承公证需要集齐一沓证明材料,群众要跑好几个部门;如今,滨海...
武清区扎实推进兴业富农 绘就乡... 转自:天津日报  初夏时节,灿烂的阳光夹杂着阵阵微风,深情抚慰着大运河畔的武清区南蔡村镇丁家瞿阝村。...
如皋农商银行:双向奔赴谋发展 ... 4月27日,如皋农商银行举办“跨境人民币赋能外贸企业发展”专题培训会。会议邀请跨境人民币业务优质企业...
泰州农商银行联合海陵区供销总社... 日前,泰州农商银行与泰州市海陵区供销总社在城中街道联合举办“政银携手进社区 惠民助农促消费”系列活动...
将虾苗卖到“小龙虾之乡” □四川日报全媒体记者 陈丽霏  5月,鲜活肥美的小龙虾大量上市,中江县黄鹿镇也迎来了一年中最繁忙的时...
建圈强链 四川农业明确产业“路... 5月11日,四川省大邑县现代农业(粮食产业)园区,工人在试验田中开展小麦新品的测产工作。 李旭 摄(...