跳转到内容
主菜单
主菜单
移至侧栏
隐藏
导航
首页
最近更改
随机页面
MediaWiki帮助
代码酷
搜索
搜索
中文(中国大陆)
外观
创建账号
登录
个人工具
创建账号
登录
未登录编辑者的页面
了解详情
贡献
讨论
编辑“︁
C++spancpp20
”︁
页面
讨论
大陆简体
阅读
编辑
编辑源代码
查看历史
工具
工具
移至侧栏
隐藏
操作
阅读
编辑
编辑源代码
查看历史
常规
链入页面
相关更改
特殊页面
页面信息
外观
移至侧栏
隐藏
您的更改会在有权核准的用户核准后向读者展示。
警告:
您没有登录。如果您进行任何编辑,您的IP地址会公开展示。如果您
登录
或
创建账号
,您的编辑会以您的用户名署名,此外还有其他益处。
反垃圾检查。
不要
加入这个!
= C++20 的 `std::span` 简介 = `std::span` 是 C++20 引入的一个轻量级、非拥有(non-owning)的视图(view),用于表示连续内存序列的引用。它类似于指针和长度的组合,但提供了更安全和更高级的接口。`std::span` 可以用于替代传统的 C 风格数组或指针传递方式,同时保持高效性,并且不会引入额外的内存开销。 == 核心特性 == * '''非拥有''':`std::span` 不管理内存,仅引用现有数据。 * '''连续内存''':适用于数组、`std::vector`、`std::array` 等连续存储的数据结构。 * '''动态或静态长度''':支持编译时固定长度(`std::span<T, N>`)或运行时动态长度(`std::span<T>`)。 * '''类型安全''':通过模板参数确保类型正确性。 == 基本语法 == {{syntaxhighlight|cpp #include <span> #include <iostream> #include <vector> void print_span(std::span<int> s) { for (int elem : s) { std::cout << elem << ' '; } std::cout << '\n'; } int main() { int arr[] = {1, 2, 3, 4, 5}; std::vector<int> vec = {6, 7, 8, 9, 10}; // 从数组创建 span std::span<int> span_arr(arr); print_span(span_arr); // 输出: 1 2 3 4 5 // 从 vector 创建 span std::span<int> span_vec(vec); print_span(span_vec); // 输出: 6 7 8 9 10 // 子视图 std::span<int> subspan = span_vec.subspan(1, 3); print_span(subspan); // 输出: 7 8 9 } }} === 输入与输出 === {{syntaxhighlight|text 输入: - 数组 `arr`: {1, 2, 3, 4, 5} - 向量 `vec`: {6, 7, 8, 9, 10} 输出: 1 2 3 4 5 6 7 8 9 10 7 8 9 }} == 动态与静态长度 == `std::span` 可以指定固定长度(编译时已知)或动态长度(运行时确定): {{syntaxhighlight|cpp // 动态长度(默认) std::span<int> dynamic_span = vec; // 静态长度(N=5) std::span<int, 5> static_span(arr); }} == 实际应用场景 == === 1. 替代指针和长度参数 === 传统 C 风格函数: {{syntaxhighlight|cpp void process_data(int* data, size_t size); }} 使用 `std::span` 更安全: {{syntaxhighlight|cpp void process_data(std::span<int> data); }} === 2. 高效传递子范围 === 无需复制数据即可操作子序列: {{syntaxhighlight|cpp void analyze_subrange(std::span<const double> data) { auto first_half = data.first(data.size() / 2); // 处理前半部分数据 } }} === 3. 与标准库容器交互 === `std::span` 与 `std::vector`、`std::array` 无缝协作: {{syntaxhighlight|cpp std::vector<float> values = {1.1f, 2.2f, 3.3f}; std::span<float> value_span(values); value_span[1] *= 2; // 修改原数据 }} == 内存布局示意图 == <mermaid> graph LR A[std::vector<int> vec] -->|数据| B[内存块: 1, 2, 3, 4, 5] C[std::span<int> s] -->|引用| B D[子视图 s.subspan(1,2)] -->|引用| B[内存块: 2, 3] </mermaid> == 数学表示 == `std::span` 可以形式化表示为: <math> \text{span}(T) = (p, n) \quad \text{其中} \quad p \in T^*, n \in \mathbb{N} </math> 其中: * <math>p</math> 是指向连续内存的指针 * <math>n</math> 是元素数量 == 注意事项 == * 确保 `std::span` 的生命周期不超过其引用的数据。 * 不可用于非连续容器(如 `std::list`)。 * 默认情况下不保证线程安全。 == 总结 == `std::span` 是 C++20 中用于高效、安全处理连续数据的工具,尤其适合以下场景: * 替代指针+长度的传统参数传递 * 避免不必要的内存拷贝 * 提供对数据的零开销抽象视图 通过合理使用 `std::span`,可以显著提升代码的安全性和可读性,同时保持 C++ 的高效特性。 [[Category:编程语言]] [[Category:C++]] [[Category:C++stl 容器]]
摘要:
请注意,所有对代码酷的贡献均被视为依照知识共享署名-非商业性使用-相同方式共享发表(详情请见
代码酷:著作权
)。如果您不希望您的文字作品被随意编辑和分发传播,请不要在此提交。
您同时也向我们承诺,您提交的内容为您自己所创作,或是复制自公共领域或类似自由来源。
未经许可,请勿提交受著作权保护的作品!
取消
编辑帮助
(在新窗口中打开)
该页面使用的模板:
模板:Syntaxhighlight
(
编辑
)