std::span 是 c++20 引入的轻量级非拥有式数组视图,仅持指针和长度,用于安全高效传递连续内存片段,避免拷贝与裸指针误用,支持编译期/运行期边界约束,但不管理内存生命周期。

std::span 是 C++20 引入的轻量级非拥有式数组视图,它不管理内存,只持有指向连续元素的指针和长度,用于安全、高效地传递数组或容器片段,避免不必要的拷贝和裸指针误用。
基本用法:构造与访问
span 可由原生数组、std::Array、std::vector(或其他支持 data() + size() 的容器)构造,类型推导通常自动完成:
- // 原生数组
int arr[] = {1, 2, 3, 4, 5};
std::spans1{arr}; // 推导为 span - // std::array
std::arraya = {1.1, 2.2, 3.3};
std::spans2{a}; - // std::vector(运行时大小)
std::vectorv(100);
std::spans3{v}; // span 等价于 span
关键安全特性:边界检查与静态约束
span 在编译期(固定大小)或运行期(动态大小)提供越界防护(仅在启用调试断言如 _ITERATOR_DEBUG_LEVEL=2 或使用 at() 时);更重要的是,它明确表达“我只读/写这一段”,并阻止隐式降维或越界切片:
- 使用
s.subspan(2, 3)安全获取子视图,超出范围会截断或返回空 span(不抛异常) -
s.first(3)和s.last(2)分别取前 N 个、后 N 个元素,同样做范围约束 - 若声明为
std::span,传入 5 元素数组会编译失败——强制匹配尺寸
函数参数设计:替代 T* + size_t 的现代写法
把 span 当作首选参数类型,能提升接口清晰度和安全性:
立即学习“C++免费学习笔记(深入)”;
- // 旧方式:易错、无长度绑定
void process(int* data, size_t n); - // 新方式:语义明确、自动适配多种来源
void process(std::spandata) {
for (int x : data) { /* … */ }
} - 调用时可传
process(arr)、process(v)、process(v.subspan(1, 4)),无需手动传 size
注意事项与常见误区
span 本身不延长所指对象生命周期,使用时需确保源数据存活时间 ≥ span 生命周期: