0

0

c++的decltype关键字是什么 类型推导的另一种方式【详解】

尼克

尼克

发布时间:2025-12-30 15:06:57

|

311人浏览过

|

来源于php中文网

原创

decltype是C++11用于编译期按表达式“形式”推导声明类型的关键词,不求值;规则分三类:标识符/成员访问得原声明类型,函数调用得返回类型(含引用),其他表达式依值类别定(lvalue→T&,prvalue→T,xvalue→T&&);括号改变语义,如decltype(x)为int而decltype((x))为int&;常用于模板精准转发、依赖表达式的变量声明、尾置返回类型及SFINAE。

c++的decltype关键字是什么 类型推导的另一种方式【详解】

decltype 是 C++11 引入的关键字,用于在编译期**根据表达式推导出其类型**,不求值、不执行,只看表达式的“形式”和上下文。它和 auto 都属于类型推导机制,但逻辑完全不同:auto 看的是初始化表达式的**结果类型**,而 decltype 看的是表达式本身的**声明类型(declared type)**,尤其关注表达式是左值还是右值、是否带括号、是否是函数调用等细节。

decltype 的基本规则

decltype(e) 的结果类型由表达式 e 的形式决定,核心有三条规则:

  • 如果 e 是一个标识符(如变量名)或类成员访问(如 obj.member),decltype(e) 就是该实体的声明类型(含 const/volatile/引用限定);
  • 如果 e 是一个函数调用或重载运算符调用(如 f(), a + b),且返回类型不是引用,decltype(e) 是返回类型;若返回类型是 T&,则 decltype(e) 是 T&;
  • 如果 e 是其他任意表达式(比如加法、解引用、带括号的变量),且 e 是纯右值(prvalue),decltype(e) 是其类型;若 e 是左值(lvalue),decltype(e) 是 T&;若 e 是 xvalue(如 std::move(x)),decltype(e) 是 T&&。

括号对 decltype 的影响很关键

加不加括号会彻底改变推导结果,这是最容易忽略的点:

  • int x = 42;decltype(x)int(x 是标识符);
  • decltype((x))int&((x) 是左值表达式,不是标识符);
  • decltype(42)int(字面量是纯右值);
  • decltype(std::move(x))int&&(xvalue 表达式)。

decltype 的典型用途

它不是为了“猜类型”而存在,而是解决 auto 无法处理的场景:

Proface Avatarize
Proface Avatarize

一个利用AI技术提供高质量专业头像和头像的工具

下载

立即学习C++免费学习笔记(深入)”;

  • **模板中精确转发返回类型**:比如实现通用的 min/max,需保持原类型的 cv 和引用属性;
  • **声明依赖于参数类型的变量**:例如 decltype(a + b) sum = a + b;,确保 sum 类型与 a+b 完全一致(可能为 long long、double 或自定义类型);
  • **配合 trailing-return-type 在函数声明中延迟写返回类型**:auto func() -> decltype(expr),尤其适用于 lambda 或复杂表达式;
  • **SFINAE 和类型特征探测**:在模板元编程中判断某个表达式是否合法(如是否有某个成员函数)。

decltype 和 auto 的对比要点

两者互补,不是替代关系:

  • auto x = expr; → 推导的是 expr 求值后的对象类型(忽略顶层 const,去掉引用);
  • decltype(x) y = expr; → y 的类型严格等于 x 的声明类型(保留 const、引用、volatile);
  • auto 要求 expr 可求值、有初始化;decltype 不要求 expr 可执行,甚至可以是未定义的函数调用(只要语法合法);
  • decltype 更“底层”,更贴近语言规则;auto 更“高层”,更贴近程序员直觉。

相关专题

更多
java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

1434

2023.10.24

Go语言中的运算符有哪些
Go语言中的运算符有哪些

Go语言中的运算符有:1、加法运算符;2、减法运算符;3、乘法运算符;4、除法运算符;5、取余运算符;6、比较运算符;7、位运算符;8、按位与运算符;9、按位或运算符;10、按位异或运算符等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

222

2024.02.23

php三元运算符用法
php三元运算符用法

本专题整合了php三元运算符相关教程,阅读专题下面的文章了解更多详细内容。

84

2025.10.17

mysql标识符无效错误怎么解决
mysql标识符无效错误怎么解决

mysql标识符无效错误的解决办法:1、检查标识符是否被其他表或数据库使用;2、检查标识符是否包含特殊字符;3、使用引号包裹标识符;4、使用反引号包裹标识符;5、检查MySQL的配置文件等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

176

2023.12.04

Python标识符有哪些
Python标识符有哪些

Python标识符有变量标识符、函数标识符、类标识符、模块标识符、下划线开头的标识符、双下划线开头、双下划线结尾的标识符、整型标识符、浮点型标识符等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

270

2024.02.23

java标识符合集
java标识符合集

本专题整合了java标识符相关内容,想了解更多详细内容,请阅读下面的文章。

250

2025.06.11

c++标识符介绍
c++标识符介绍

本专题整合了c++标识符相关内容,阅读专题下面的文章了解更多详细内容。

121

2025.08.07

c语言const用法
c语言const用法

const是关键字,可以用于声明常量、函数参数中的const修饰符、const修饰函数返回值、const修饰指针。详细介绍:1、声明常量,const关键字可用于声明常量,常量的值在程序运行期间不可修改,常量可以是基本数据类型,如整数、浮点数、字符等,也可是自定义的数据类型;2、函数参数中的const修饰符,const关键字可用于函数的参数中,表示该参数在函数内部不可修改等等。

518

2023.09.20

JavaScript 性能优化与前端调优
JavaScript 性能优化与前端调优

本专题系统讲解 JavaScript 性能优化的核心技术,涵盖页面加载优化、异步编程、内存管理、事件代理、代码分割、懒加载、浏览器缓存机制等。通过多个实际项目示例,帮助开发者掌握 如何通过前端调优提升网站性能,减少加载时间,提高用户体验与页面响应速度。

3

2025.12.30

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
10分钟--Midjourney创作自己的漫画
10分钟--Midjourney创作自己的漫画

共1课时 | 0.1万人学习

Midjourney 关键词系列整合
Midjourney 关键词系列整合

共13课时 | 0.9万人学习

AI绘画教程
AI绘画教程

共2课时 | 0.2万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号