C++23中std::span和std::basic_string_view可平凡复制提案解析
文章目录
- 一、引言
- 二、相关概念解释
- 2.1 平凡复制(Trivially Copyable)
- 2.2 `std::span`
- 2.3 `std::basic_string_view`
- 三、`std::span`和`std::basic_string_view`的应用场景
- 3.1 `std::span`的应用场景
- 3.2 `std::basic_string_view`的应用场景
- 四、P2251R1提案对`std::span`和`std::basic_string_view`的改变和影响
- 4.1 改变
- 4.2 影响
- 4.2.1 性能提升
- 4.2.2 与其他库和工具的兼容性增强
- 4.2.3 代码可移植性和一致性提高
- 五、总结
一、引言
在C++的发展历程中,每一个新版本都带来了一系列令人期待的新特性,这些特性不仅提升了语言的性能和表达能力,还为开发者提供了更加便捷和高效的编程方式。C++23作为C++标准的一个重要版本,在很多方面进行了完善和优化。其中,P2251R1提案要求std::span
和std::basic_string_view
可平凡复制,这一改变对C++编程产生了重要影响。
二、相关概念解释
2.1 平凡复制(Trivially Copyable)
平凡复制是C++中的一个重要概念。一个类型如果是平凡复制的,意味着它可以通过简单的内存复制(如memcpy
)来进行复制操作,而不需要执行任何自定义的复制构造函数或赋值运算符。平凡复制类型具有以下特点:
- 具有平凡的默认构造函数:即编译器自动生成的默认构造函数。
- 具有平凡的复制构造函数:即编译器自动生成的复制构造函数。
- 具有平凡的移动构造函数:即编译器自动生成的移动构造函数。
- 具有平凡的复制赋值运算符:即编译器自动生成的复制赋值运算符。
- 具有平凡的移动赋值运算符:即编译器自动生成的移动赋值运算符。
- 具有平凡的析构函数:即编译器自动生成的析构函数。
在C++编程中,平凡复制类型在性能优化、内存管理等方面具有重要意义。例如,在进行数据的批量复制时,平凡复制类型可以直接使用memcpy
等高效的内存复制函数,从而提高程序的执行效率。
2.2 std::span
std::span
是C++20引入的一种轻量级非拥有性容器,用于表示连续内存区域的视图。它不管理内存的所有权,而是通过指针和大小描述一段数据,类似于“智能指针 + 长度”的组合。其核心设计目标包括零拷贝、类型安全和接口统一。
std::span
支持动态和静态两种范围:
- 动态范围:大小在运行时确定,使用
std::dynamic_extent
表示。例如:std::span<int> dynamic_span(arr, 3);
- 静态范围:大小在编译时确定,性能更高。例如:
std::span<int, 3> static_span(arr);
std::span
的优势在于提高代码的安全性和可读性,以及轻量级与高性能。它可以作为函数参数,统一处理不同类型的连续数据源,减少函数重载;同时,其内存开销低,编译器可以对其进行优化,确保运行时性能。
2.3 std::basic_string_view
std::basic_string_view
是C++17引入的一个轻量级的非拥有型字符串表示,它设计用来提供对字符序列的引用。std::basic_string_view
不拥有它所表示的字符串,它只是提供了一种方式来引用或“查看”存储在其他地方的字符串,比如一个std::string
或者字符数组。
与std::string
相比,std::basic_string_view
具有以下特点:
- 非拥有:不管理内存,只是对现有字符串的引用。
- 只读:不能通过
basic_string_view
修改字符串内容。 - 低成本:构造和操作的开销很低,适合传递字符串参数而不需要拷贝。
std::basic_string_view
通常用于需要传递字符串参数而不需要拷贝,以及需要高效的字符串操作,如查找、比较等场景。
三、std::span
和std::basic_string_view
的应用场景
3.1 std::span
的应用场景
- 作为函数参数:
std::span
是传递连续数据的理想选择,可以替代传统的指针和容器引用。它不仅简化了函数接口,还提高了通用性和安全性。例如:
#include <iostream>
#include <span>void process(std::span<const int> data) {for (int v : data) {std::cout << v << " ";}std::cout << std::endl;
}int main() {int arr[] = {1, 2, 3, 4, 5};process(arr);return 0;
}
- 与标准库算法结合:
std::span
可以与C++20的范围库(Ranges)无缝集成,支持声明式编程。例如:
#include <iostream>
#include <span>
#include <ranges>
#include <vector>int main() {std::vector<int> vec = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};std::span<int> s(vec);auto evenNumbers = s | std::views::filter([](int x) { return x % 2 == 0; });for (int n : evenNumbers) {std::cout << n << " ";}std::cout << std::endl;return 0;
}
- 处理多维数组:
std::span
也可以用于处理多维数组,通过subspan()
方法实现数据切片。
3.2 std::basic_string_view
的应用场景
- 函数参数:当函数需要处理字符串时,使用
std::basic_string_view
作为参数可以避免不必要的字符串复制,提高性能。例如:
#include <iostream>
#include <string_view>void print_string_view(std::string_view sv) {std::cout << "String view: " << sv << std::endl;
}int main() {std::string str = "Hello, World!";print_string_view(str);return 0;
}
- 字符串处理和分析:
std::basic_string_view
提供了一系列字符串处理方法,如find
、substr
等,可以高效地进行字符串分析。例如:
#include <iostream>
#include <string_view>int main() {std::string_view sv = "Hello, World!";auto pos = sv.find("World");if (pos != std::string_view::npos) {std::cout << "Found 'World' at position: " << pos << std::endl;}return 0;
}
四、P2251R1提案对std::span
和std::basic_string_view
的改变和影响
4.1 改变
在C++23之前,虽然std::basic_string_view
在实际实现中通常是平凡复制的,但并没有正式的标准要求。而std::span
也没有明确规定为平凡复制类型。P2251R1提案明确要求std::span
和std::basic_string_view
必须是平凡复制类型,这意味着它们的复制构造函数、移动构造函数、复制赋值运算符和移动赋值运算符都必须是平凡的。
4.2 影响
4.2.1 性能提升
由于std::span
和std::basic_string_view
现在是平凡复制类型,在进行复制操作时可以直接使用高效的内存复制函数(如memcpy
),而不需要调用自定义的构造函数或赋值运算符,从而提高了复制操作的性能。特别是在处理大量数据或频繁进行复制操作的场景中,性能提升更为明显。
4.2.2 与其他库和工具的兼容性增强
平凡复制类型在很多库和工具中具有更好的兼容性。例如,在使用一些底层库进行内存操作时,平凡复制类型可以更方便地与这些库进行交互,减少了额外的转换和处理步骤。
4.2.3 代码可移植性和一致性提高
明确规定std::span
和std::basic_string_view
为平凡复制类型,使得不同编译器和实现之间的行为更加一致,提高了代码的可移植性。开发者在编写代码时可以更加放心地使用这些类型,不用担心不同平台上的行为差异。
五、总结
P2251R1提案要求std::span
和std::basic_string_view
可平凡复制,这是C++23标准中的一个重要改进。这一改变不仅提升了std::span
和std::basic_string_view
的性能,还增强了它们与其他库和工具的兼容性,提高了代码的可移植性和一致性。在实际编程中,开发者可以更加高效地使用std::span
和std::basic_string_view
,充分发挥它们的优势,编写更加高效、安全和可维护的代码。
相关文章:

C++23中std::span和std::basic_string_view可平凡复制提案解析
文章目录 一、引言二、相关概念解释2.1 平凡复制(Trivially Copyable)2.2 std::span2.3 std::basic_string_view 三、std::span和std::basic_string_view的应用场景3.1 std::span的应用场景3.2 std::basic_string_view的应用场景 四、P2251R1提案对std::…...

[yolov11改进系列]基于yolov11引入感受野注意力卷积RFAConv的python源码+训练源码
[RFAConv介绍] 1、RFAConv 在传统卷积操作中,每个感受野都使用相同的卷积核参数,无法区分不同位置的信息差异,这都限制了网络性能。此外,由于空间注意力以及现有空间注意力机制的局限性,虽然能够突出关键特征…...

Springboot引入Spring Cloud for AWS的配置中心(Parameter Store和Secrets)
问题 现在手上有一个老Spring2.5.15项目,需要使用AWS Parameter Store作为配置中心服务。 思路 引入这个Spring版本对应的Spring Cloud,然后再引入Spring Cloud AWS相关组件。然后,在AWS云上面准备好配置,然后,启动…...

打破云平台壁垒支持多层级JSON生成的MQTT网关技术解析
工业智能网关的上行通信以MQTT协议为核心,但在实际应用中,企业往往需要将数据同时或分场景接入多个公有云平台(如华为云IoT、阿里云IoT、亚马逊AWS IoT),甚至私有化部署的第三方平台。为实现这一目标,网关需…...
Modbus通信中的延迟和时间间隔详解
在工业自动化领域,Modbus协议作为最广泛使用的通信协议之一,其通信时序和延迟控制直接影响到系统的稳定性和效率。本文将深入探讨Modbus通信中涉及的各种延迟和时间间隔,帮助开发者更好地理解和应用这些概念。 一、串口Modbus通信中的延迟问题 1.1 为什么需要延迟? 在基…...
maven 最短路径依赖优先
问题描述: 项目在升级大版本后出现了,两个不同模块所引用的同一个依赖包版本不同 module A 引用了 module B,module B 引用了 A_1.0.jar->B_1.0.jar->C_1.0.jar(C 为B 里面的包) 在执行 mvn dependency:tree 后发现: modul…...

SAAS架构设计2-流程图-用户与租户之间对应关系图
在SAAS(Software as a Service,软件即服务)结构中,用户与租户之间的关系可以通过一对一和多对多两种方式来定义。这两种关系模式各自有着不同的应用场景和特点。 用户和租户的关系(一对一) 一对一关系 在这…...

TypeScript入门到精通
学习ts之前,我们首先了解一下我们为什么要学ts,ts是什么?ts比js有不同呢? TypeScript 是 JavaScript 的一个超集,是由微软开发的自由和开源的编程语言,支持 ECMAScript 6 标准(ES6 教程)。在 Ja…...

三、Docker目录挂载、卷映射、网络
目录挂载 如果主机目录为空,则容器内也为空 -v表示目录挂载 冒号前面的是主机上的目录,冒号后面的是docker容器里面的地址 修改主机上的文件,发现docker容器里面的内容也随之改变。 同样修改docker容器里面的内容,主机上的文件…...

迪米特法则 (Law of Demeter, LoD)
定义:迪米特法则(Law of Demeter, LoD):一个软件实体应当尽可能少地与其他实体发生相互作用。 迪米特法则(Law of Demeter,LoD)又叫作最少知识原则(Least Knowledge Principle,LKP),…...

【R语言编程绘图-函数篇】
基础函数绘制 R语言可通过curve()函数直接绘制数学函数图形,无需预先生成数据点。例如绘制正弦函数: curve(sin, from -pi, to pi, col "blue", lwd 2)自定义函数绘制 对于用户自定义函数,需先定义函数表达式: …...

训练自己的yolo模型,并部署到rk3588上
文章目录 1. 训练自己的模型2. pt转onnx3. onnx转rknn4. 后续…… 1. 训练自己的模型 如何训练自己的yolo模型,网络上已经有足够多的教程,这里只简单的描述一下。如果已经有了自己的.pt模型,那么可以直接跳转到第二节。 此处是以检测模型的…...
Leetcode 3556. Sum of Largest Prime Substrings
Leetcode 3556. Sum of Largest Prime Substrings 1. 解题思路2. 代码实现3. 算法优化 题目链接:3556. Sum of Largest Prime Substrings 1. 解题思路 这一题毕竟只是这一次双周赛的第一题,虽然标记为medium的题目,但是思路上还是非常简单…...

以少学习:通过无标签数据从大型语言模型进行知识蒸馏
Learning with Less: Knowledge Distillation from Large Language Models via Unlabeled Data 发表:NNACL-Findings 2025 机构:密歇根州立大学 Abstract 在实际的自然语言处理(NLP)应用中,大型语言模型(…...
鸿蒙OSUniApp 实现带有滑动删除的列表#三方框架 #Uniapp
使用 UniApp 实现带有滑动删除的列表 在移动应用开发中,滑动删除(Swipe to Delete)是一种常见且实用的交互方式,广泛应用于消息、待办、收藏等列表场景。用户只需在列表项上左右滑动,即可快速删除或管理数据。随着 Ha…...

Qt qml Network error问题
最近在学习Qt,需要调用地图,所以用到了QML,但是却遇到了这样的问题 d://qt_project//run//main.qml: Network error 现在我展示一下我的main文件的代码: #include <QApplication> #include <QQuickView> #include &l…...
Prompt工程:解锁大语言模型的终极密钥
Prompt工程:解锁大语言模型的终极密钥 一、引言:Prompt的战略价值重构 在人工智能技术加速渗透的2025年,Prompt(提示词)作为连接人类意图与大语言模型(LLM)的核心接口,其战略地位已…...

Spring Boot微服务架构(六):伪装的微服务有哪些问题?
伪装的微服务有哪些问题? 伪装的微服务架构(即表面上模仿微服务设计,但未真正遵循其核心原则的系统)通常具备以下特征点,这些特征可能导致系统复杂度增加、维护困难或性能下降: 1. 服务间强耦合 …...

恶意npm与VS Code包窃取数据及加密货币资产
60个npm包窃取系统敏感信息 安全研究人员在npm软件包注册表中发现60个恶意组件,这些组件能够收集主机名、IP地址、DNS服务器和用户目录信息,并将其发送至Discord平台控制的终端节点。据Socket安全研究员Kirill Boychenko上周发布的报告显示,…...
Matlab快速上手五十六:详解符号运算里假设的用法,通过假设可以设置符号变量的取值范围,也可以通过假设设置变量属于集合:整数、正数和实数等
1.符号变量中假设的概念 在符号数学工具箱中,符号变量默认范围是全体复数,也就是说,符号运算是在全体复数域进行的,若需要运算中,不使用全体复数域,可以为变量设定取值范围,这就用到了假设&…...
机器学习笔记【Week1】
一、机器学习简介(Introduction) 什么是机器学习? 定义(Tom Mitchell): “A computer program is said to learn from experience E with respect to some task T and performance measure P, if its per…...

什么是3D全景视角?3D全景有什么魅力?
什么是3D全景视角?3D全景视角的全面解析。 3D全景视角,又称为3D全景技术或3D实景技术,是新兴的富媒体技术,基于静态图像和虚拟现实(VR)技术,通过全方位、无死角地捕捉和展示环境,为…...

【Mini-F5265-OB开发板试用测评】按键控制测试
本文介绍了如何使用按键控制 MCU 引脚的输出电平。 原理 由原理图可知 板载用户按键 K1 和 K2 分别与主控的 PB0 和 PB1 相连。 代码 #define _MAIN_C_#include "platform.h" #include "gpio_key_input.h" #include "main.h"int main(void) …...
Debian重装系统后
安装配置java环境 手动安装 下载openJDK:openJDK 设置替代项 sudo update-alternatives --install /usr/bin/java java /opt/jdk-21.0.2/bin/java 1 sudo update-alternatives --install /usr/bin/javac javac /opt/jdk-21.0.2/bin/javac 1 sudo update-alternat…...

每日Prompt:古花卷
提示词 主体对象 一本展开的古画卷 古画卷内呈现的内容 一片微型春秋鲁国,有古代马车,孔子乘坐周游列国,颜回、子路、子贡、曾参紧随其后 古画卷的外观状态 表面已经开裂和风化,呈现出年代感和历史感 与文字描述的首句一致&…...
[学习]C语言指针函数与函数指针详解(代码示例)
C语言指针函数与函数指针详解 文章目录 C语言指针函数与函数指针详解一、引言二、指针函数(函数返回指针)定义与语法典型应用场景注意事项 三、函数指针(指向函数的指针)定义与声明初始化与调用赋值方式调用语法 高级应用回调函数…...

夏季用电高峰如何防患于未“燃”?电力测温技术守护城市生命线
随着夏季来临用电负荷激增,电力系统面临严峻的高温考验,电力测温技术的重要性愈发凸显,电力安全是城市生命线工程的核心环节,电力测温已从"可选功能"升级为"必要的基础安全设施"。通过实时感知、智能分析和快…...
浙大版《Python 程序设计》题目集6-3,6-4,6-5,6-6列表或元组的数字元素求和及其变式(递归解法)
目录 6-3 输入格式: 输出格式: 输入样例: 输出样例: 6-4 输入格式: 输出格式: 输入样例: 输出样例: 6-5 输入格式: 输出格式: 输入样例: 输出样例: 6-6 输入格式: 输出格式: 输入样例: 输出样例: 6-3 第6章-3 列表或元组的数字元素求和 分数 20 全屏浏览 切换布局 作者 陈春晖 …...
Leetcode 3563. Lexicographically Smallest String After Adjacent Removals
Leetcode 3563. Lexicographically Smallest String After Adjacent Removals 1. 解题思路2. 代码实现 题目链接:3563. Lexicographically Smallest String After Adjacent Removals 1. 解题思路 这次的最后一题同样没有自力搞定,简直了…… 这道题还…...

【创造型模式】抽象工厂方法模式
文章目录 抽象工厂方法模式产品族与产品等级结构抽象工厂方法模式的角色和职责抽象工厂方法模式的实现抽象工厂方法模式的优缺点适用场景 抽象工厂方法模式 工厂方法模式引入了“工厂等级结构”,解决了简单工厂方法过分依赖单一工厂的问题。但是工厂方法模式存在的一…...