基本概念

decltype 是 C++11 引入的关键字,用于推导表达式的类型,且会完整保留类型的细节(包括 const、引用 &、指针 * 等)。

语法:decltype(表达式) 变量名

核心特点

1.推导依据是表达式本身,而非表达式的结果(与 auto 不同)。
例:int x = 5; decltype(x) a; → a 的类型是 int(因 x 是 int)。
2.完整保留类型修饰符:

  • 若表达式是 const int&,则推导出的类型也是 const int&。
  • 若表达式是 int*,则推导出的类型也是 int*。

使用场景

1. 模板中推导复杂返回值类型

当模板函数的返回值类型依赖于参数类型,且无法通过 auto 直接推导时(如返回值是参数表达式的结果),decltype 能自动推导正确类型。

template<typename T, typename U>
auto add(T a, U b) -> decltype(a + b) {  // 推导 a+b 的类型作为返回值return a + b;
}
int main(){int x = 1;double y = 2.5;auto result = add(x, y);  // 返回值类型自动推导为 double
}

2. 保留引用和 const 修饰符

auto会丢失引用和const,但decltype能完整保留。

int x = 10;
const int& ref = x;  // ref 是 const int&auto a = ref;        // a 是 int(丢失 const 和引用)
decltype(ref) b = x; // b 是 const int&(保留所有修饰符)

3. 推导容器元素的引用类型

在泛型代码中,获取容器元素的引用类型(如vector<int>::reference),避免拷贝。用auto占位,decltype实际推导。

#include <vector>template<typename Container>
auto get_first(Container& c) -> decltype(c[0]) {  // 返回容器元素的引用类型return c[0];
}// 使用:
std::vector<int> vec = {1, 2, 3};
get_first(vec) = 100;  // 修改原容器的第一个元素(返回值是 int&)

4. 捕获 lambda 表达式的类型

lambda的类型是匿名的,只能用decltype捕获。

auto lambda = [](int x) { return x * 2; };
decltype(lambda) another_lambda = lambda;  // 复制 lambda 类型

5.定义与成员指针同类型的变量

当类型涉及复杂的成员指针时,用decltype自动推导

struct Person {std::string name;int age;
};Person p{"Alice", 20};
decltype(&Person::age) ptr = &Person::age;  // ptr 指向 Person::age,类型是 int Person::*// 1. 访问对象的成员
int value = p.*ptr;      // 等价于 p.age(通过对象访问)
int value2 = (&p)->*ptr; // 等价于 p.age(通过指针访问)// 2. 修改对象的成员
p.*ptr = 21;  // 等价于 p.age = 21;

实际场景(成员指针举例)

用 decltype 简化成员指针的类型声明
struct Person {std::string name;int age;
};// 通用函数:修改 Person 的任意成员
template<typename T>
void set_member(Person& p, T Person::* member_ptr, T value) {p.*member_ptr = value;  // 统一修改成员的逻辑
}int main() {Person p{"Alice", 20};// 1. 动态选择修改 age 成员(用 decltype 简化类型声明)decltype(&Person::age) age_ptr = &Person::age;  // 等价于 int Person::* age_ptrset_member(p, age_ptr, 21);  // 调用通用函数修改 age// 2. 动态选择修改 name 成员(同样用 decltype)decltype(&Person::name) name_ptr = &Person::name;  // 等价于 std::string Person::* name_ptrset_member(p, name_ptr, "Bob");  // 调用同一个通用函数修改 name// 结果:p.age=21,p.name="Bob"
}

decltype 在这个例子里的作用:

1.自动推导成员指针的复杂类型

  • &Person::age 的类型是 int Person::*(手动写很繁琐),decltype 直接推导出这个类型,避免手写错误。
  • &Person::name 的类型是 std::string Person::*decltype 同样能自动搞定。

2.适配通用函数
通用函数 set_member 需要知道成员的类型 Tdecltype 推导出的 age_ptr 和 name_ptr 能完美匹配函数的模板参数,让同一个函数处理不同类型的成员(int 和 std::string)。

为什么必须用 decltype?

如果不用 decltype,就需要手动写成员指针的类型:

int Person::* age_ptr = &Person::age;  // 繁琐且容易写错
std::string Person::* name_ptr = &Person::name;

而用 decltype 只需 decltype(&Person::age) age_ptr,尤其是在成员类型复杂(比如自定义类型)时,decltype 能大幅减少代码量和错误率。

与auto的区别与联系

对比项decltypeauto
推导依据表达式的类型本身(不执行表达式)变量初始化的值(执行表达式)
类型保留完整保留 const、引用等修饰符会忽略引用(除非显式加 &
适用场景推导复杂类型、模板返回值简化变量定义(如 auto x = 5;

联系:两者常配合使用(如模板函数的尾随返回类型),auto 占位,decltype 负责精准推导。

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

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

相关文章

RPC 与 Feign 的区别笔记

一、基本概念 1.1 RPC&#xff08;Remote Procedure Call&#xff09; 定义&#xff1a;远程过程调用&#xff0c;允许像调用本地方法一样调用远程服务的方法。 本质&#xff1a;跨进程通信&#xff0c;隐藏了底层网络通信的复杂性。 常见实现&#xff1a; Java 原生 RMIDub…

高防IP能够防御CC攻击吗?它具备哪些显著优势?

摘要&#xff1a; 面对日益复杂的网络攻击&#xff0c;高防IP作为重要的安全工具&#xff0c;不仅能防御常见的DDoS攻击&#xff0c;还能有效应对CC攻击。本文将解析高防IP防御CC攻击的原理及其核心优势&#xff0c;帮助读者了解其在网络安全中的关键作用。一、高防IP能否防御C…

TypeScript 类型注解(一)

一、TypeScript 类型注解1、什么是TpyeScript类型注解- 是否还记得TypeScript的两个重要特性&#xff1f;- 类型系统、适用于任何规模- 可以说&#xff0c;TS的类型系统是TS最重要的功能&#xff1b;那么什么是类型注解呢&#xff1f;其实就是在声明变量时&#xff0c;将变量的…

弗兰肯斯坦式的人工智能与GTM策略的崩溃

2025 年上半年已经明确了一件事&#xff1a;B2B 市场营销团队被工具淹没&#xff0c;但缺乏策略。人工智能无处不在。收入领导者在进行无休止的试点。营销团队拼凑各种点解决方案&#xff0c;希望能实现规模扩张。然而&#xff0c;销售线索的增长停滞不前。信誉正在受损。曾经承…

NAND闪存(NAND Flash)是什么?

NAND闪存(NAND Flash)是什么? NAND闪存(NAND Flash)详解 NAND闪存是一种非易失性存储介质(断电不丢失数据),广泛应用于SSD、U盘、手机存储等设备中。NAND Flash 的全称是 “Negative-AND Flash”(与非型闪存),其名称源自其底层存储单元的电路结构——基于**“与非门…

Android性能优化之UI渲染优化

一、UI渲染核心瓶颈深度解析 1. 渲染管线关键阶段阶段CPU工作GPU工作潜在卡顿点Measure计算View尺寸-嵌套布局多次测量Layout计算View位置-频繁重排(Relayout)Draw构建DisplayList指令集-复杂自定义View.onDraw()Sync & Upload资源上传到GPU内存纹理上传大图/未压缩资源Ras…

基于Spring AI Alibaba的智能知识助手系统:从零到一的RAG实战开发

&#x1f4d6; 项目概述 在人工智能快速发展的今天&#xff0c;RAG&#xff08;Retrieval-Augmented Generation&#xff09;技术已成为构建智能问答系统的核心技术。本文将详细介绍一个基于Spring AI Alibaba DashScope深度集成的智能知识助手系统的完整开发过程&#xff0c;…

VirtualBox + CentOS:启用 DHCP 获取 IPv4 地址

标题&#xff1a; VirtualBox CentOS&#xff1a;启用 DHCP 获取 IPv4 地址 日期&#xff1a; 2025-07-18 一、问题现象 最小化安装的 CentOS 7 虚拟机里敲&#xff1a; ip addr输出只有 lo 的 127.0.0.1 以及 enp0s3 的 IPv6 链路本地地址&#xff0c;没有 IPv4&#xff0…

Git

Git简介Git 是一个分布式版本控制工具&#xff0c;通常用来对软件开发过程中的源代码文件进行管理。通过Git 仓库来存储和管理这些文件&#xff0c;Git 仓库分为两种:本地仓库:开发人员自己电脑上的 Git仓库。远程仓库:远程服务器上的 Git 仓库。commit: 提交, 将本地文件和版本…

通信算法之294:LTE系统中的整数倍频偏估计

在LTE系统中&#xff0c;整数倍频偏估计主要通过以下方法实现&#xff1a;一、最大似然估计法&#xff08;ML&#xff09;通过遍历预设的整数倍频偏范围&#xff08;如30kHz&#xff09;&#xff0c;将接收信号与本地的PSS序列在不同频偏点上进行相关运算&#xff0c;选择相关峰…

数字人直播:开启直播行业新纪元​

​原始尺寸更换图片p9-flow-imagex-sign.byteimg.com​​在科技日新月异的当下&#xff0c;直播行业正经历着一场深刻变革&#xff0c;数字人直播的兴起&#xff0c;宛如一颗璀璨新星&#xff0c;照亮了直播领域的新征程。数字人直播&#xff0c;是利用先进的人工智能技术&…

朝鲜升级供应链恶意软件XORIndex,再次瞄准npm生态系统

Socket威胁研究团队最新披露&#xff0c;朝鲜国家支持的黑客组织在"传染性面试"攻击活动中采用了新型恶意软件加载器XORIndex&#xff0c;该恶意程序专门通过npm软件包注册表渗透软件供应链。攻击规模与持续性此次攻击并非孤立事件&#xff0c;而是针对开发者、求职者…

Windows 下 VS2019 编译 libevent-2.1.10 库

1. 你需要VS2019 编译好openssl-1.1.1 &#xff0c;这个具体编译或者下载可以参考我的博客openssl生成的库是这两个文件接下来&#xff0c;打开CMake &#xff0c;主要是下面的需要设置好最后Config Generate即可&#xff1b;全部成功生成 22个然后INSTALL右键生成 最后看下生…

Vim多列操作指南

我们在使用 Vim 时&#xff0c;经常需要同时编辑多个文件&#xff0c;或者同一个文件的不同部分。Vim 提供了分割窗口&#xff08;split&#xff09;和垂直分割窗口&#xff08;vsplit&#xff09;的功能&#xff0c;允许我们在同一个 Vim 会话中查看多个缓冲区&#xff08;buf…

Python网络爬虫实现selenium对百度识图二次开发以及批量保存Excel

一.百度识图自动上传图片from selenium import webdriver from selenium.webdriver.edge.options import Options from selenium.webdriver.common.by import By edge_options Options() edge_options.binary_location r"C:\Program Files (x86)\Microsoft\Edge\Applica…

Vue中的refs字段使用记录

这段代码是 Vue.js 中结合 Element UI 等 UI 库的典型表单验证写法&#xff0c;具体含义如下&#xff1a;代码拆解 this.$refs.fromData.validate((valid) > {// 验证后的回调逻辑 })this.$refs.fromData $refs 是 Vue 提供的特殊属性&#xff0c;用于访问模板中通过 ref&qu…

多方案对比分析:后端数据加密策略及实践

多方案对比分析&#xff1a;后端数据加密策略及实践 随着互联网业务对用户隐私和数据安全的要求不断提升&#xff0c;后端系统中对敏感数据的加密保护已成为必备需求。从对称加密、非对称加密到数据库透明加密、应用层字段加密&#xff0c;各种方案各有特点。本文将以方案对比分…

《Java语言程序设计》1.4 复习题

1.4.1 什么是操作系统?列出一些流行的操作系统?操作系统(Operating System)是运行在计算机上的最重要的程序。操作系统管理和控制计算机的活动。通用计算机的流行操作系统有Microsoft Windows、Mac OS以及Linux。如果没有在计算机上安装和运行操作系统&#xff0c;像Web浏览器…

OpenCV图像自动缩放(Autoscaling)函数autoscaling()

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 该函数用于对输入图像进行自动缩放&#xff08;Autoscaling&#xff09;&#xff0c;即根据输入图像的像素值范围将其线性映射到一个新的范围内&am…

多线程的认识

竞争与协作在单核 CPU 系统里&#xff0c;为了实现多个程序同时运行的假象&#xff0c;操作系统通常以时间片调度的方式&#xff0c;让每个进程执行每次执行一个时间片&#xff0c;时间片用完了&#xff0c;就切换下一个进程运行&#xff0c;由于这个时间片的时间很短&#xff…