当前位置: 首页 > news >正文

C++26 新特性预览(Preview)

文章目录

    • 1. 静态反射 (Static Reflection)
      • 示例: 枚举转字符串
      • 应用场景
    • 2. 合约 (Contracts)
      • 示例: 定义函数合约
      • 应用场景
    • 3. 条件中的结构化绑定 (Structured Bindings in Conditions)
      • 示例: 改进的错误处理
      • 应用场景
    • 4. 包索引 (Pack Indexing)
      • 示例: 获取参数包的第一个和最后一个元素
      • 应用场景
    • 5. 饱和算术 (Saturation Arithmetic)
      • 示例: 安全算术操作
      • 应用场景
    • 6. 为函数`delete`标记添加说明
      • 应用场景
    • 7. 匿名占位符的改进
    • 8. 用户自定义 `static_assert` 错误信息
    • 9. 为花括号初始化的内容提供静态存储支持
    • 10. 新的头文件`<debugging>`
    • 总结

C++26 引入了一系列新功能, 进一步提升了语言的灵活性, 性能和易用性. 本文将列举其中的一些新特性, 并通过代码示例帮助您快速掌握.


1. 静态反射 (Static Reflection)

静态反射允许开发者在编译时查询和操作类型信息, 为元编程提供了强大的支持. 这一特性极大地简化了类型处理, 自动生成代码等复杂任务.

示例: 枚举转字符串

#include <experimental/meta>
#include <iostream>
#include <string>
#include <type_traits>template <typename E>requires std::is_enum_v<E>
constexpr std::string enum_to_string(E value) {std::string result = "<unnamed>";[:expand(std::meta::enumerators_of(^E)):] >> [&]<auto e> {if (value == [:e:]) {result = std::meta::identifier_of(e);}};return result;
}enum Color { red, green, blue };
static_assert(enum_to_string(Color::red) == "red");
static_assert(enum_to_string(Color(42)) == "<unnamed>");int main() {Color red = Color::red;std::cout << enum_to_string(red) << std::endl;return 0;
}

应用场景

  • 类型描述自动生成: 通过反射轻松提取类型信息.
  • 代码生成工具: 基于反射实现自动代码生成和序列化.
  • 复杂元编程: 减少模板代码的复杂性.

2. 合约 (Contracts)

合约为函数定义前置条件, 后置条件和断言, 提升代码的可靠性.

示例: 定义函数合约

#include <contracts> // 合约支持的头文件int divide(int numerator, int denominator)pre (denominator != 0)                   // 前置条件: 分母不能为 0post (result: result * denominator == numerator) // 后置条件: 结果 * 分母 == 分子
{contract_assert(numerator >= 0);         // 断言: 分子必须是非负数return numerator / denominator;
}

应用场景

  • 输入验证: 确保函数调用的参数满足预期.
  • 逻辑验证: 自动检测计算结果是否符合约定.
  • 调试工具: 通过断言捕捉潜在的逻辑错误.

注意: 此功能目前仍需特定编译器支持.


3. 条件中的结构化绑定 (Structured Bindings in Conditions)

C++26 引入了在 ifwhile 条件语句中使用结构化绑定的能力, 进一步简化了错误处理流程.

示例: 改进的错误处理

#include <charconv>
#include <cstring>
#include <iostream>void parse_int(char* str) {if (auto [ptr, ec] = std::to_chars(str, str + std::strlen(str), 42);ec == std::errc{}) {std::cout << "Parsed successfully.\n";} else {std::cerr << "Failed to parse: " << str << "\n";}
}int main() {const char* buffer = "42";parse_int(buffer);  // 输出: Parsed successfully.return 0;
}

在 Compiler Explorer 中查看示例

应用场景

  • 简化异常处理: 在条件语句中直接解构返回值.
  • 提高可读性: 通过解构直接获取多个结果.

4. 包索引 (Pack Indexing)

包索引让开发者能直接访问模板参数包中的特定元素, 简化模板编程.

示例: 获取参数包的第一个和最后一个元素

#include <iostream>
#include <tuple>template <typename... Args>
constexpr auto first_and_last(Args... args) {return std::make_pair(Args...[0], Args...[sizeof...(Args) - 1]);
}int main() {auto [first, last] = first_and_last(1, 2, 3, 4, 5);std::cout << "First: " << first << ", Last: " << last << "\n";return 0;
}

注意: 当前示例基于提案实现, 需等待特定编译器支持.

应用场景

  • 元组操作: 直接访问和操作元组中的特定元素.
  • 参数解包: 在模板编程中高效地解包和处理参数包.
  • 代码生成: 简化生成代码时对参数包的处理.
  • 编译时计算: 在编译时对参数包进行索引和计算, 提高编译期的灵活性.
  • 容器操作: 在自定义容器中高效地访问和操作元素.

5. 饱和算术 (Saturation Arithmetic)

饱和算术为加减乘除提供安全操作, 避免溢出.

示例: 安全算术操作

#include <iostream>
#include <numeric>  // 包含饱和算术的定义int main() {// 饱和加法int add_result = std::add_sat<signed char>(100, 30);std::cout << "Saturated Add: " << add_result << "\n";  // 输出: 127// 饱和减法int sub_result = std::sub_sat<signed char>(-100, 30);std::cout << "Saturated Sub: " << sub_result << "\n";  // 输出: -128// 饱和乘法int mul_result = std::mul_sat<signed char>(100, 30);std::cout << "Saturated Mul: " << mul_result << "\n";  // 输出: 127// 类型转换的饱和long large_value = 150;int saturated_cast_result = std::saturate_cast<signed char>(large_value);std::cout << "Saturated Cast: " << saturated_cast_result<< "\n";  // 输出: 127return 0;
}

在 Compiler Explorer 中打开

应用场景

  • 图像处理: 确保像素值在合法范围内(如 0-255).
  • 嵌入式系统: 防止溢出带来的意外行为.

6. 为函数delete标记添加说明

通过为delete标记添加说明, 开发者能更清晰地了解函数为何被删除.

#include <functional>void NewAPI();
void OldAPI() = delete("OldAPI() is outdated and been removed - use NewAPI().");template <class T>
auto cref(const T&) -> std::reference_wrapper<const T>;template <class T>
auto cref(const T&&) = delete("cref(rvalue) is dangerous!");int main() {int i = 0;auto r1 = std::cref(i);   // OKauto r2 = std::cref(42);  // Error, best match is deletedreturn 0;
}

在 Compiler Explorer 中打开

参考这篇博客:What =delete means

应用场景

  • API 更新: 清晰地标记过时的函数, 引导用户使用新的 API.
  • 安全性: 阻止危险的函数调用, 提高代码的安全性.

7. 匿名占位符的改进

#include <tuple>[[nodiscard]] int foo() { return 0; }[[nodiscard]] std::tuple<int, int, double> tuple() { return {0, 1, 1.0}; }int multi() {auto _ = 1;                  // OKauto _ = 2.0;                // OK, no conflictauto _ = "string";           // OK, no conflictauto [ret, _, _] = tuple();  // OK, no conflict// return _; // Error, `_` has multi definitionreturn ret;
}int main() {// before C++26[[maybe_unused]] int a = foo();  // OKstd::ignore = foo();             // OKstatic_cast<void>(foo());        // Not recommended// from C++26auto _ = foo();auto _ = multi();auto [ret, _, _] = tuple();return ret;
}

在 Compiler Explorer 中打开

8. 用户自定义 static_assert 错误信息

#include <format>template <typename T>
void test_fun(T a) {static_assert(sizeof(T) == 1,std::format("Unexpected sizeof: expect 1, got {}", sizeof(T)));
}int main() {test_fun('c');  // OK// test_fun(1);    // error
}

在 Compiler Explorer 中打开

9. 为花括号初始化的内容提供静态存储支持

std::vector<char> v = {#embed "2mb-image.png"
};

这段代码中的 #embed 指令可以让大型文件的数据在编译时直接嵌入为静态存储的一部分, 从而提高加载效率.

10. 新的头文件<debugging>

#include <debugging>
int main() {std::breakpoint_if_debugging();  // stop if in debugger
}

尚无编译器支持.

总结

C++26 的特性为现代 C++ 编程带来了更多的灵活性和高效性, 通过这些改进, C++ 程序员将能够更轻松地编写出高性能的现代化代码.

相关文章:

C++26 新特性预览(Preview)

文章目录 1. 静态反射 (Static Reflection)示例: 枚举转字符串应用场景 2. 合约 (Contracts)示例: 定义函数合约应用场景 3. 条件中的结构化绑定 (Structured Bindings in Conditions)示例: 改进的错误处理应用场景 4. 包索引 (Pack Indexing)示例: 获取参数包的第一个和最后一…...

MySQL5.7.26-Linux-安装(2024.12)

文章目录 1.下载压缩包1.访问MySQL版本归档2.找到5.7.26并下载3.百度网盘 2.Linux安装1.卸载原来的MySQL8.0.26&#xff08;如果没有则无需在意&#xff09;1.查看所有mysql的包2.批量卸载3.删除残留文件**配置文件**&#xff08;默认路径&#xff09;&#xff1a; 4.**验证卸载…...

2025-1-2-sklearn学习(30)模型选择与评估-验证曲线: 绘制分数以评估模型 真珠帘卷玉楼空,天淡银河垂地。

文章目录 sklearn学习(30) 模型选择与评估-验证曲线: 绘制分数以评估模型30.1. 验证曲线30.2. 学习曲线 sklearn学习(30) 模型选择与评估-验证曲线: 绘制分数以评估模型 文章参考网站&#xff1a; https://sklearn.apachecn.org/ 和 https://scikit-learn.org/stable/ 每种估…...

【优选算法】查找总价格为目标值的两个商品

链接&#xff1a;LCR 179. 查找总价格为目标值的两个商品 - 力扣&#xff08;LeetCode&#xff09; 解法&#xff1a;利用单调性&#xff0c;使用双指针算法解决问题 1.先从小到大排序 2. sum > t : right--; sum < t : left; sum t : return class Solution {public…...

利用 NineData 实现 PostgreSQL 到 Kafka 的高效数据同步

记录一次 PostgreSQL 到 Kafka 的数据迁移实践。前段时间&#xff0c;NineData 的某个客户在一个项目中需要将 PostgreSQL 的数据实时同步到 Kafka。需求明确且普遍&#xff1a; PostgreSQL 中的交易数据&#xff0c;需要实时推送到 Kafka&#xff0c;供下游多个系统消费&#…...

future和CompletableFuture

future 什么是future Future 类是并发编程中一个非常重要的工具。它主要用于表示一个异步计算的结果&#xff0c;允许你在计算完成后获取结果或处理异常。Java 的 Future 也常常与线程池&#xff08;如 ExecutorService&#xff09;结合使用&#xff0c;用来执行并行任务&…...

如何通过深度学习提升大分辨率图像预测准确率?

随着科技的不断进步&#xff0c;图像处理在各个领域的应用日益广泛&#xff0c;特别是在医疗影像、卫星遥感、自动驾驶、安防监控等领域中&#xff0c;大分辨率图像的使用已经成为了一项不可或缺的技术。然而&#xff0c;大分辨率图像带来了巨大的计算和存储压力&#xff0c;同…...

【机器学习】机器学习的基本分类-半监督学习-Ladder Networks

Ladder Networks 是一种半监督学习模型&#xff0c;通过将无监督学习与监督学习相结合&#xff0c;在标记数据较少的情况下实现高效的学习。它最初由 A. Rasmus 等人在 2015 年提出&#xff0c;特别适合深度学习任务&#xff0c;如图像分类或自然语言处理。 核心思想 Ladder N…...

[react]小技巧, ts如何声明点击事件的类型

很简单, 鼠标放到事件上面就行了 如果想知道点击的是什么元素 ,打印他的nodename就行了 不过得断言为html元素才行 const handleClick (e: React.MouseEvent<HTMLDivElement, MouseEvent>) > {console.log(current, (e.target as HTMLElement).nodeName);}; 为什么…...

智能工厂的设计软件 应用场景的一个例子:为AI聊天工具添加一个知识系统 之9 重新开始 之2

本文要点 对程序设计而言&#xff1a;前者基于一个自上而下的 分类体系--&#xff08;生物遗传基因&#xff09;&#xff0c;后者者需要一个收集差异的自下而上的差异继承路径--&#xff08;系统继承源流&#xff09; 就是 广义和狭义 分类学。 共性对齐 和 差异收集 正是两者…...

【从零开始】11. LLaMA-Factory 微调 Qwen 模型(番外篇)

书接上回&#xff0c;在完成了 RAGChecker 测试后&#xff0c;离 RAG 应用真正发布还差最后一步 - 基础信息指令微调。考虑到模型还是需要具备一定程度的“自我认知”&#xff0c;因此需要将公司信息“嵌入”到模型里面的。为此&#xff0c;我选择了 LLaMA-Factory&#xff08;…...

WPF使用ContentControl控件实现区域导航,并使用Prism依赖注入优化

背景&#xff1a;使用ContentControl控件实现区域导航是有Mvvm框架的WPF都能使用的&#xff0c;不限于Prism 主要是将ContenControl控件的Content内容在ViewModel中切换成不同的用户控件 下面是MainViewModel&#xff1a; private object body;public object Body {get { retu…...

JavaWeb——MySQL-DML(1/3)-添加数据insert(DML 操作概述、INSERT 语句插入数据、语句演示、总结)

目录 DML 操作概述 INSERT 语句插入数据 INSERT 语句基础语法 INSERT 语句演示 注意事项 总结 DML 操作概述 DML 简介 DML&#xff08;Data Manipulation Language&#xff09;即数据操作语言&#xff0c;用于对数据库表中的数据进行增删改操作&#xff0c;包括添加数据&…...

经验证:将数据从索尼传输到Android的 4 种方法

概括 像Android Galaxy S20 这样的新型Android智能手机很酷&#xff0c;但除了将数据从索尼传输到Android之外。众所周知&#xff0c;旧的索尼手机上存储着大量的文件&#xff0c;因此将数据从旧的索尼手机传输到新的Android手机非常重要。为了解决这个问题&#xff0c;我们做…...

嵌入式应用实例→电子产品量产工具→UI界面的绘制和测试

前言 之前已经在博文https://blog.csdn.net/wenhao_ir/article/details/144747714中实现了用Freetype在LCD屏上绘制字符&#xff0c;本篇博文我们利用Freetype实现UI界面的绘制。 头文件include\ui.h的分析 头文件内的代码 #ifndef _UI_H #define _UI_H#include <common…...

如何删除 Docker 中的悬虚镜像?

在 Docker 中&#xff0c;悬虚镜像&#xff08;Dangling Images&#xff09;是指那些没有 标签 且没有被任何容器使用的镜像。这些镜像通常是由于构建过程中生成的中间层镜像或未正确清理的镜像残留。删除悬虚镜像可以释放磁盘空间并保持 Docker 环境的整洁。 1. 列出悬虚镜像…...

el-table树形懒加载展开改为点击行展开

思路&#xff1a;获取el-table中小箭头&#xff0c;然后调它的click事件&#xff01; <el-tablerow-click"getOpenDetail":row-class-name"tableRowClassName">// 点击当前行展开节点getOpenDetail(row, column, event) {// 如果是叶子节点或点击的是…...

【Ubuntu】Ubuntu server 18.04 搭建Slurm并行计算环境(包含NFS)

Ubuntu server 18.04 搭建Slurm并行计算环境&#xff08;包含NFS&#xff09; 一、Munge 认证模块 1.1、安装 munge 主节点和子节点都安装munge #安装 sudo apt update && sudo apt install munge libmunge-dev#设置开机启动 sudo systemctl enable munge sudo syste…...

高并发场景下的秒杀系统架构设计与实现

引言 秒杀系统是一种高并发场景的典型应用&#xff0c;广泛存在于电商平台、抢票系统和促销活动中。秒杀活动的特点是短时间内吸引大量用户同时访问并尝试抢购商品&#xff0c;这对系统的高并发处理能力、稳定性和用户体验提出了极高的要求。 在秒杀系统中&#xff0c;常见的…...

搭建开源版Ceph分布式存储

系统&#xff1a;Rocky8.6 三台2H4G 三块10G的硬盘的虚拟机 node1 192.168.2.101 node2 192.168.2.102 node3 192.168.2.103 三台虚拟机环境准备 1、配置主机名和IP的映射关系 2、关闭selinux和firewalld防火墙 3、配置时间同步且所有节点chronyd服务开机自启 1、配置主机名和…...

2025年能源电力系统与流体力学国际会议 (EPSFD 2025)

2025年能源电力系统与流体力学国际会议&#xff08;EPSFD 2025&#xff09;将于本年度在美丽的杭州盛大召开。作为全球能源、电力系统以及流体力学领域的顶级盛会&#xff0c;EPSFD 2025旨在为来自世界各地的科学家、工程师和研究人员提供一个展示最新研究成果、分享实践经验及…...

遍历 Map 类型集合的方法汇总

1 方法一 先用方法 keySet() 获取集合中的所有键。再通过 gey(key) 方法用对应键获取值 import java.util.HashMap; import java.util.Set;public class Test {public static void main(String[] args) {HashMap hashMap new HashMap();hashMap.put("语文",99);has…...

高频面试之3Zookeeper

高频面试之3Zookeeper 文章目录 高频面试之3Zookeeper3.1 常用命令3.2 选举机制3.3 Zookeeper符合法则中哪两个&#xff1f;3.4 Zookeeper脑裂3.5 Zookeeper用来干嘛了 3.1 常用命令 ls、get、create、delete、deleteall3.2 选举机制 半数机制&#xff08;过半机制&#xff0…...

376. Wiggle Subsequence

376. Wiggle Subsequence 代码 class Solution { public:int wiggleMaxLength(vector<int>& nums) {int n nums.size();int res 1;int prediff 0;int curdiff 0;for(int i 0;i < n-1;i){curdiff nums[i1] - nums[i];if( (prediff > 0 && curdif…...

OkHttp 中实现断点续传 demo

在 OkHttp 中实现断点续传主要通过以下步骤完成&#xff0c;核心是利用 HTTP 协议的 Range 请求头指定下载范围&#xff1a; 实现原理 Range 请求头&#xff1a;向服务器请求文件的特定字节范围&#xff08;如 Range: bytes1024-&#xff09; 本地文件记录&#xff1a;保存已…...

视频字幕质量评估的大规模细粒度基准

大家读完觉得有帮助记得关注和点赞&#xff01;&#xff01;&#xff01; 摘要 视频字幕在文本到视频生成任务中起着至关重要的作用&#xff0c;因为它们的质量直接影响所生成视频的语义连贯性和视觉保真度。尽管大型视觉-语言模型&#xff08;VLMs&#xff09;在字幕生成方面…...

令牌桶 滑动窗口->限流 分布式信号量->限并发的原理 lua脚本分析介绍

文章目录 前言限流限制并发的实际理解限流令牌桶代码实现结果分析令牌桶lua的模拟实现原理总结&#xff1a; 滑动窗口代码实现结果分析lua脚本原理解析 限并发分布式信号量代码实现结果分析lua脚本实现原理 双注解去实现限流 并发结果分析&#xff1a; 实际业务去理解体会统一注…...

排序算法总结(C++)

目录 一、稳定性二、排序算法选择、冒泡、插入排序归并排序随机快速排序堆排序基数排序计数排序 三、总结 一、稳定性 排序算法的稳定性是指&#xff1a;同样大小的样本 **&#xff08;同样大小的数据&#xff09;**在排序之后不会改变原始的相对次序。 稳定性对基础类型对象…...

C++课设:简易日历程序(支持传统节假日 + 二十四节气 + 个人纪念日管理)

名人说:路漫漫其修远兮,吾将上下而求索。—— 屈原《离骚》 创作者:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊) 专栏介绍:《编程项目实战》 目录 一、为什么要开发一个日历程序?1. 深入理解时间算法2. 练习面向对象设计3. 学习数据结构应用二、核心算法深度解析…...

Qt的学习(一)

1.什么是Qt Qt特指用来进行桌面应用开发&#xff08;电脑上写的程序&#xff09;涉及到的一套技术Qt无法开发网页前端&#xff0c;也不能开发移动应用。 客户端开发的重要任务&#xff1a;编写和用户交互的界面。一般来说和用户交互的界面&#xff0c;有两种典型风格&…...