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 用于推导表达式的类型,它会保留表达式的所有类型信息(包括引用、
const、
volatile 等修饰符)。其规则可以分为以下几种情况:
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&。 - 表达式是右值(临时对象):推导结果为
T或T&&(取决于表达式类型)。
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 的区别
decltype 与 auto 的关键区别在于:
-
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 是右值,推导为 T 或 T&&。 |
decltype(expr) | 根据 expr 的值类别推导:- 左值 → T&- 右值 → T 或 T&&。 |
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推导表达式类型。 - 完美转发:与
decltype和std::forward配合使用。 - 类型萃取:在
type_traits中生成类型信息。
总结
decltype 的规则核心是:
- 保留表达式的完整类型信息(包括引用和修饰符)。
- 根据值类别推导表达式结果的类型(左值 →
T&,右值 →T或T&&)。 - 与
auto互补:decltype更适合需要精确控制类型的场景(如泛型编程)。
相关文章:
C++ decltype 规则推导
C decltype 规则推导 文章目录 C decltype 规则推导**1. 基本规则****(1) 如果 decltype 的参数是变量名(无括号的标识符)****(2) 如果 decltype 的参数是表达式(带括号或操作符)** **2. 与 auto 的区别****3. 特殊场景****(1) 函…...
Rust 测试组织指南:单元测试与集成测试
一、为什么要同时使用单元测试与集成测试 单元测试:更为精细、聚焦某一逻辑单元;可以调用到私有函数,快速定位错误根源。集成测试:作为“外部代码”来使用库的公开接口,测试多个模块间的交互,确保整体功能…...
Day62_补20250210_图论part6_108冗余连接|109.冗余连接II
Day62_20250210_图论part6_108冗余连接|109.冗余连接II 108冗余连接 【把题意转化为并查集问题】 题目 有一个图,它是一棵树,他是拥有 n 个节点(节点编号1到n)和 n - 1 条边的连通无环无向图(其实就是一个线形图&am…...
kafka消费端之消费者协调器和组协调器
文章目录 概述回顾历史老版本获取消费者变更老版本存在的问题 消费者协调器和组协调器新版如何解决老版本问题再均衡过程**第一阶段CFIND COORDINATOR****第二阶段(JOINGROUP)**选举消费组的lcader选举分区分配策略 第三阶段(SYNC GROUP&…...
语法备忘04:将 事件处理函数 绑定到 组件 的事件上
示例1:<Table OnQueryAsync"OnQueryAsync" /> 示例2:<Table OnQueryAsync"OnQueryAsync" /> 说明:这两种写法在功能上是完全相同的,都是在将 OnQueryAsync 事件处理函数绑定到 Table 组件的 …...
C++20中的std::atomic_ref
一、std::atomic_ref 我们在学习C11后的原子操作时,都需要提前定义好std::atomic变量,然后才可以在后续的应用程序中进行使用。原子操作的优势在很多场合下优势非常明显,所以这也使得很多开发者越来习惯使用原子变量。 但是,在实…...
CSS 相关知识
1、高度已知,三栏布局,左右宽度 200,中间自适应,如何实现? <body><div class"box"><div class"box1">高度已知</div><div class"box2">左右宽度 200&…...
RocketMQ、RabbitMQ、Kafka 的底层实现、功能异同、应用场景及技术选型分析
1️⃣ 引言 在现代分布式系统架构中,📩消息队列(MQ)是不可或缺的组件。它在系统🔗解耦、📉流量削峰、⏳异步处理等方面发挥着重要作用。目前,主流的消息队列系统包括 🚀RocketMQ、&…...
IDEA升级出现问题Failed to prepare an update Temp directory inside installation
IDEA升级出现问题"Failed to prepare an update Temp directory inside installation…" 问题来源: 之前修改了IDEA的默认配置文件路径,然后升级新版本时就无法升级,提示"Failed to prepare an update Temp directory insid…...
DeepSeek提示词手册
一、核心原则:基于DeepSeek的推理特性 自然语言优先undefinedDeepSeek擅长理解自然表达,无需复杂模板。例如: ❌旧模板:"你是专业分析师,需分三步回答,第一步…" ✅高效提问:"…...
基于UVM搭验证环境
基于UVM搭验证环境基本思路: 首先,我们搭建环境时一般都有一个目标的DUT。此时,我们可以结合所要验证的的模块、是否需要VIP、验证侧重点等在典型的UVM验证环境的基础上做适当调整后形成一个大体的环境架构。比如,需要一个ahb_vip…...
C++性能优化—人工底稿版
C以高性能著称,性能优化是C程序员绕不过去的一个话题,性能优化是一个复杂、全局而又细节的问题,本文总结C性能分析中常用的知识。 性能优化的时机 大部分关于性能优化的文章都强调:不要过早的进行性能优化。 C编码层面 数据结…...
Java 使用腾讯翻译 API 实现含 HTML 标签文本精准翻译工具
一、翻译标签文本工具 package org.springblade.common.utils;import java.util.ArrayList; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern;public class TencentTranslationForHTML {public static void main(String[] args) {Stri…...
十款开源的论坛建站工具
以下是十款开源的论坛建站工具,它们各具特色,能够满足不同用户的需求: Discuz!(Crossday Discuz! Board) 特点:基础架构采用web编程组合PHPMySQL,用户可以在不需要任何编程的基础上,…...
vue学习6
1. 智慧商城 1. 路由设计配置 单个页面,独立展示的,是一级路由 2.二级路由配置 规则&组件配置导航链接配置路由出口 <template><div id"app"><!--二级路由出口--><router-view></router-view><van-…...
线程池以及日志、线程总结
一、线程池以及日志 1、基础线程池写法 主线程在main函数中构建一个线程池,初始化(Init)后开始工作(Start) 此时线程池中每个线程都已经工作起来了,只是任务队列中任务为空,所有线程处于休眠状态(通过线程同步中的条件变量实现,…...
Vue 响应式渲染 - 过滤应用
Vue 渐进式JavaScript 框架 基于Vue2的学习笔记 - Vue响应式渲染综合 - 过滤应用 目录 过滤应用 引入vue Vue设置 设置页面元素 模糊查询过滤实现 函数表达式实现 总结 过滤应用 综合响应式渲染做一个输入框,用来实现;搜索输入框关键词符合列表。…...
【ThreeJS Basics 1-3】Hello ThreeJS,实现第一个场景
文章目录 环境创建一个项目安装依赖基础 Web 页面概念解释编写代码运行项目 环境 我的环境是 node version 22 创建一个项目 首先,新建一个空的文件夹,然后 npm init -y , 此时会快速生成好默认的 package.json 安装依赖 在新建的项目下用 npm 安装依…...
银行国际结算
银行国结项目,即国际结算项目,是银行业务中的重要组成部分,它涉及跨国界的货币收付和资金转移。 一、银行国结项目的定义 银行国结项目是指银行为国际贸易、投资等活动提供的国际结算服务,包括各种国际支付和资金清算业务。这些…...
Go语言构建微服务:从入门到实战
引言 在云原生时代,微服务架构已成为构建复杂分布式系统的首选方案。Go语言凭借其卓越的并发支持、简洁的语法和高效的运行时,成为微服务开发的利器。本文将深入探讨如何用Go构建健壮的微服务系统,并通过完整案例演示关键实现细节。 一、微…...
深入理解动态代理
为什么需要动态代理 对于代码的增强逻辑我们是清楚具体实现的,一种方式是增强逻辑作为委托类,被其他业务类调用, 这样会有很多重复代码,而且,当需要根据动态参数来决定增强逻辑时,重复代码会更多,逻辑会更不清晰 二,也是动态代理产生的原始需求,解决类爆照问题, 所以…...
私有属性和方法(python)
一、私有属性(属性名前面加两个短下划线) (一)私有属性与公有属性区别 公有属性:在类里面和外面均可以访问和修改 私有属性:需要用set方法才能修改,get方法才能访问 (二…...
Cherry Studio之DeepSeek联网/本地,建属于自己的AI助理!
上一篇文章,讲了DeepSeek-R1部署到本地的方法。这一篇文章,我们让DeepSeek再一次升级,通过图形化界面来交互,从而变成我们的AI助理,让DeepSeek R1发挥最大实力! 首选需要借助硅基流动的API接口,…...
TcpClientTest
ClientTest: using System; using System.Net.Sockets; using System.Text;class TcpClientTest {static void Main(string[] args){try{// 创建一个TcpClient实例并连接到服务器 TcpClient client new TcpClient("1vg5062570.51mypc.cn", 43319);//1v…...
IGBT的两级关断
IGBT(绝缘栅双极型晶体管)的两级关断(Two-stage turn-off)是一种优化关断过程的方法,主要用于减少关断时的电压过冲和dv/dt(电压变化率)过高的问题,特别是在大功率应用中(…...
【STM32】ADC
本次实现的是ADC实现数字信号与模拟信号的转化,数字信号时不连续的,模拟信号是连续的。 1.ADC转化的原理 模拟-数字转换技术使用的是逐次逼近法,使用二分比较的方法来确定电压值 当单片机对应的参考电压为3.3v时,0~ 3.3v(模拟信号…...
从MyBatis-Plus看Spring Boot自动配置原理
一、问题引入:神秘的配置生效之谜 当我们使用MyBatis-Plus时,只需在pom.xml中添加依赖: <dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3…...
0基础租个硬件玩deepseek,蓝耘元生代智算云|本地部署DeepSeek R1模型
前言:哈喽,大家好,今天给大家分享一篇文章!并提供具体代码帮助大家深入理解,彻底掌握!创作不易,如果能帮助到大家或者给大家一些灵感和启发,欢迎收藏关注哦 💕 目录 0基础…...
雪花算法应用
什么是雪花算法? 雪花算法是由 Twitter 开源的分布式 ID 生成算法,用于生成 64 位的长整型唯一 ID。其结构如下: - 1 位符号位:始终为 0 - 41 位时间戳:精确到毫秒 - 10 位工作机器 ID:包含 5 位数据中心 …...
Chapter3:结构化程序设计
参考书籍:《C#边做边学》; 3.结构化程序设计 3.1 结构化程序设计的3种基本结构 顺序结构:先执行 A {\rm A} A语句,再执行 B {\rm B} B语句,两者是顺序执行的关系; 选择结构:根据所定选择条件为…...
