C++ decltype 规则推导

C++ decltype 规则推导

文章目录

  • C++ decltype 规则推导
    • **1. 基本规则**
      • **(1) 如果 `decltype` 的参数是变量名(无括号的标识符)**
      • **(2) 如果 `decltype` 的参数是表达式(带括号或操作符)**
    • **2. 与 `auto` 的区别**
    • **3. 特殊场景**
      • **(1) 函数返回类型推导(C++11 后)**
      • **(2) `decltype(auto)`(C++14 引入)**
      • **(3) 成员变量推导**
    • **4. 推导规则总结**
    • **5. 示例与注意事项**
      • **(1) 示例:推导函数返回值**
      • **(2) 示例:避免悬垂引用**
      • **(3) 注意事项**
    • **6. 应用场景**
    • **总结**

C++ 中的 decltype 用于推导表达式的类型,它会保留表达式的所有类型信息(包括引用、 constvolatile 等修饰符)。其规则可以分为以下几种情况:


1. 基本规则

(1) 如果 decltype 的参数是变量名(无括号的标识符)

  • 推导结果为该变量的声明类型,包括所有修饰符(如 const、引用等)。

    int x = 10;
    const int& rx = x;
    int arr[3] = {1, 2, 3};decltype(x) a = x;     // a 的类型是 int
    decltype(rx) b = x;    // b 的类型是 const int&
    decltype(arr) c;       // c 的类型是 int[3](保留数组类型)
    

(2) 如果 decltype 的参数是表达式(带括号或操作符)

  • 根据表达式的值类别(value category)推导类型:

    • 表达式是左值(非临时对象):推导结果为 T&
    • 表达式是右值(临时对象):推导结果为 TT&&(取决于表达式类型)。
    int x = 10;
    const int cx = 20;decltype(x) a = x;       // a 的类型是 int
    decltype((x)) b = x;     // b 的类型是 int&((x) 是左值表达式)
    decltype(cx) c = cx;     // c 的类型是 const int
    decltype((cx)) d = cx;   // d 的类型是 const int&
    decltype(42) e = 42;     // e 的类型是 int(42 是右值)
    decltype(x + 0) f;       // f 的类型是 int(表达式结果是右值)
    

2. 与 auto 的区别

decltypeauto 的关键区别在于:

  • auto 推导类型时会忽略引用和顶层 const,而 decltype 会保留所有类型信息。

  • auto 的推导规则类似模板类型推导,而 decltype 直接反映表达式的静态类型。

    const int x = 10;
    const int& rx = x;auto a = x;        // a 的类型是 int(忽略顶层 const)
    decltype(x) b = x; // b 的类型是 const intauto c = rx;       // c 的类型是 int(忽略引用和 const)
    decltype(rx) d = x;// d 的类型是 const int&
    

3. 特殊场景

(1) 函数返回类型推导(C++11 后)

  • decltype 常用于后置返回类型(trailing return type)的推导:

    template<typename T, typename U>
    auto add(T a, U b) -> decltype(a + b) {return a + b;
    }
    

(2) decltype(auto)(C++14 引入)

  • decltype(auto) 结合 auto 的语法和 decltype 的推导规则:

    • 保留所有类型信息(包括引用和 const)。
    int x = 10;
    const int& rx = x;auto a = rx;             // a 的类型是 int
    decltype(auto) b = rx;   // b 的类型是 const int&
    

(3) 成员变量推导

  • decltype 可以直接推导类成员的类型:

    struct Point {int x;double y;
    };Point p;
    decltype(p.x) a = 10;    // a 的类型是 int
    decltype(Point::y) b;    // b 的类型是 double
    

4. 推导规则总结

表达式形式推导结果
decltype(var)直接推导 var 的声明类型(保留所有修饰符)。
decltype((var))var 是左值,推导为 T&;若 var 是右值,推导为 TT&&
decltype(expr)根据 expr 的值类别推导:
- 左值 → T&
- 右值 → TT&&
decltype(func())推导为函数返回值的类型(若返回值是左值,则为引用类型)。

5. 示例与注意事项

(1) 示例:推导函数返回值

int func() { return 42; }
int& func_ref() { static int x; return x; }decltype(func()) a = 42;      // a 的类型是 int
decltype(func_ref()) b = a;   // b 的类型是 int&

(2) 示例:避免悬垂引用

int* ptr = new int(42);
decltype(*ptr) c = *ptr;      // c 的类型是 int&
delete ptr;
// c 此时是悬垂引用,访问会导致未定义行为!

(3) 注意事项

  • decltype 在推导时不会执行表达式,仅静态分析类型。
  • 推导结果可能包含引用,需注意生命周期问题。

6. 应用场景

  • 模板元编程:结合 std::declval 推导表达式类型。
  • 完美转发:与 decltypestd::forward 配合使用。
  • 类型萃取:在 type_traits 中生成类型信息。

总结

decltype 的规则核心是:

  1. 保留表达式的完整类型信息(包括引用和修饰符)。
  2. 根据值类别推导表达式结果的类型(左值 → T&,右值 → TT&&)。
  3. auto 互补decltype 更适合需要精确控制类型的场景(如泛型编程)。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/15510.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

白嫖RTX 4090?Stable Diffusion:如何给线稿人物快速上色?

大家都知道&#xff0c;在设计的初期&#xff0c;我们通常会先绘制草图&#xff0c;然后再进行上色处理&#xff0c;最终才开始进行最终的设计工作。在这个上色的过程中&#xff0c;配色是至关重要的一环。这不仅方便了内部同事的评审&#xff0c;也让产品方和客户可以直观地了…

从大规模恶意攻击 DeepSeek 事件看 AI 创新隐忧:安全可观测体系建设刻不容缓

作者&#xff1a;羿莉&#xff08;萧羿&#xff09; 全球出圈的中国大模型 DeepSeek 作为一款革命性的大型语言模型&#xff0c;以其卓越的自然语言处理能力和创新性成本控制引领行业前沿。该模型不仅在性能上媲美 OpenAI-o1&#xff0c;而且在推理模型的成本优化上实现了突破…

AMD 8845HS 780M核显部署本地deepseek大模型的性能

测试了一下笔记本电脑AMD 8845HS的780M核显是否能本地部署deepseek大模型。 测试软件环境&#xff1a;LM Studio 0.3.9 、Windows 11 24H2 硬件&#xff1a;荣耀X16笔记本 CPU&#xff1a;AMD 8845HS 显卡&#xff1a;780M核显&#xff0c;显存为共享内存自动分配模式&…

利用二分法进行 SQL 盲注

什么是sql注入&#xff1f; SQL 注入&#xff08;SQL Injection&#xff09;是一种常见的 Web 安全漏洞&#xff0c;攻击者可以通过构造恶意 SQL 语句来访问数据库中的敏感信息。在某些情况下&#xff0c;服务器不会直接返回查询结果&#xff0c;而是通过布尔值&#xff08;Tr…

《深度学习》——pytorch框架及项目

文章目录 pytorch特点基本概念 项目项目实现导入所需库下载训练数据和测试数据对训练和测试样本进行分批次展示手写图片判断pytorch是否支持GPU定义神经网络模型定义训练函数定义测试函数创建交叉熵损失函数和优化器通过多轮训练降低损失值得到最终结果注意 pytorch PyTorch 是…

【批量获取图片信息】批量获取图片尺寸、海拔、分辨率、GPS经纬度、面积、位深度、等图片属性里的详细信息,提取出来后导出表格,基于WPF的详细解决方案

摄影工作室通常会有大量的图片素材&#xff0c;在进行图片整理和分类时&#xff0c;需要知道每张图片的尺寸、分辨率、GPS 经纬度&#xff08;如果拍摄时记录了&#xff09;等信息&#xff0c;以便更好地管理图片资源&#xff0c;比如根据图片尺寸和分辨率决定哪些图片适合用于…

windows生成SSL的PFX格式证书

生成crt证书: 安装openssl winget install -e --id FireDaemon.OpenSSL 生成cert openssl req -x509 -newkey rsa:2048 -keyout private.key -out certificate.crt -days 365 -nodes -subj "/CN=localhost" 转换pfx openssl pkcs12 -export -out certificate.pfx…

UnityShader学习笔记——高级纹理

——内容源自唐老狮的shader课程 目录 1.立方体纹理 1.1.概念 1.2.用处 1.3.如何采样 1.4.优缺点 2.天空盒 2.1.概念 2.2.优点 2.3.设置 3.动态生成立方体纹理 3.1.原因 3.2.实现 3.3.代码运行中生成 4.反射 4.1.原理 4.2.补充知识 5.折射 5.1.原理 5.2.菲涅…

IBM服务器刀箱Blade安装Hyper-V Server 2019 操作系统

案例:刀箱某一blade,例如 blade 5 安装 Hyper-V Server 2019 操作系统(安装进硬盘) 刀箱USB插入安装系统U盘,登录192.168... IBM BlandeCenter Restart Blande 5,如果Restart 没反应,那就 Power Off Blade 然后再 Power On 重启后进入BIOS界面设置usb存储为开机启动项 …

C++20新特性

作者&#xff1a;billy 版权声明&#xff1a;著作权归作者所有&#xff0c;商业转载请联系作者获得授权&#xff0c;非商业转载请注明出处 前言 C20 是 C 标准中的一个重要版本&#xff0c;引入了许多新特性和改进&#xff0c;包括模块&#xff08;Modules&#xff09;、协程…

WPS如何接入DeepSeek(通过JS宏调用)

WPS如何接入DeepSeek 一、文本扩写二、校对三、翻译 本文介绍如何通过 WPS JS宏调用 DeepSeek 大模型&#xff0c;实现自动化文本扩写、校对和翻译等功能。 一、文本扩写 1、随便打开一个word文档&#xff0c;点击工具栏“工具”。 2、点击“开发工具”。 3、点击“查看代码”…

【SQL server】关于SQL server彻底的卸载删除。

1.未彻底卸载删除SQL Server会出现的问题 如果没有彻底删除之前的SQL server&#xff0c;就可能会出现这个 当要安装新的实例的时候因为之前安装过sql server没有删除干净而导致下图问题&#xff0c;说实例名已经存在。 2.首先要先关闭服务 “开始R”可以快速进入运行&#…

对话框补充以及事件处理机制 (2025.2.10)

作业 1> 将鼠标事件和键盘事件相关代码重新实现一遍 2> 将文本编辑器功能完善 主函数main.cpp #include "widget.h"#include <QApplication>int main(int argc, char *argv[]) {QApplication a(argc, argv);Widget w;w.show();return a.exec(); } 头…

企业级Mysql实战

Mysql企业级sql编写实战 1 一对多&#xff0c;列表展示最新记录字段1.1 场景1.2 需求1.3 实现1.3.1 表及数据准备1.3.2 Sql编写 2 区间统计&#xff08;if/case when&#xff09;2.1 场景2.2 需求2.3 实现2.2.1 表及数据准备2.3.2 sql编写 3 多类别分组统计&#xff08;竖表转横…

C语言基础第04天:数据的输出和输出

C语言基础:04天笔记 内容提要 回顾C语言数据的输入输出 回顾 运算符 算术运算符 结果:数值 - * / % (正) -(负) -- i和i 相同点:i自身都会增1 不同点:他们运算的最终结果是不同的. i先使用 ,后加1; i先计算,后使用 赋值运算符 结果:赋值后的变量的值 赋值顺序:由右…

DeepSeek训练成本与技术揭秘

引言&#xff1a;在当今人工智能蓬勃发展的时代&#xff0c;DeepSeek 宛如一颗耀眼的新星&#xff0c;突然闯入大众视野&#xff0c;引发了全球范围内的热烈讨论。从其惊人的低成本训练模式&#xff0c;到高性能的模型表现&#xff0c;无一不让业界为之侧目。它打破了传统认知&…

数组与指针1

1. 数组名的理解 1.1 数组名是数组首元素的地址 int arr[10] {1,2,3,4,5,6,7,8,9,10};int *p &arr[0]; 这里我们使用 &arr[0] 的方式拿到了数组第一个元素的地址&#xff0c;但是其实数组名本来就是地址&#xff0c;而且是数组首元素的地址。如下&#xff1a; 1.2…

Axure原型图怎么通过链接共享

一、进入Axure 二、点击共享 三、弹出下面弹框&#xff0c;点击发布就可以了 发布成功后&#xff0c;会展示链接&#xff0c;复制即可共享给他人 四、发布失败可能的原因 Axure未更新&#xff0c;首页菜单栏点击帮助选择Axure更新&#xff0c;完成更新重复以上步骤即可

软件模拟I2C案例(寄存器实现)

引言 在经过前面对I2C基础知识的理解&#xff0c;对支持I2C通讯的EEPROM芯片M24C02的简单介绍以及涉及到的时序操作做了整理。接下来&#xff0c;我们就正式进入该案例的实现环节了。本次案例是基于寄存器开发方式通过软件模拟I2C通讯协议&#xff0c;然后去实现相关的需求。 阅…

脚手架开发【实战教程】prompts + fs-extra

创建项目 新建文件夹 mycli_demo 在文件夹 mycli_demo 内新建文件 package.json {"name": "mycli_demo","version": "1.0.0","bin": {"mycli": "index.js"},"author": "","l…