跳到主要内容
版本:1.0

span

std::span 是 C++20 引入的轻量级只读(或可读写)视图,表示一段连续内存区间。它本质上是一个指针 + 长度,不拥有数据,拷贝极轻量。

核心价值:用一个 span<T> 参数代替 T* ptr + size_t len 对,或代替 const std::vector<T>&(后者绑定了容器类型)。

头文件与基本特征

#include <span>
特征说明
所有权不拥有数据,只是"借用"
内存连续区间
编译期长度可选(span<T, N> 为固定长度视图)
替代T* + sizeconst vector<T>&(仅读时)

基本用法

#include <iostream>
#include <span>
#include <vector>

void print(std::span<const int> data) {
for (int x : data) {
std::cout << x << ' ';
}
std::cout << '\n';
}

int main() {
int arr[] = {1, 2, 3, 4, 5};
std::vector<int> v = {10, 20, 30};

print(arr); // 从 C 数组
print(v); // 从 vector
print(v.data(), 2); // 从指针 + 长度

return 0;
}

同一个函数,接受数组、vector、指针+长度——无需重载。

子区间(零拷贝切片)

std::span<int> full = arr;
std::span<int> first3 = full.first(3); // 前 3 个
std::span<int> last2 = full.last(2); // 后 2 个
std::span<int> sub = full.subspan(1, 3); // 从索引 1 开始 3 个

全是零拷贝,只是调整了指针和长度。

常用接口

接口作用
data()获取底层指针
size() / size_bytes()元素数 / 字节数
empty()是否为空
operator[]索引访问
begin() / end()迭代器
first(n) / last(n)前后切片
subspan(offset, count)中间切片

使用注意

  1. span 不拥有数据,被引用的数据必须比 span 活得久。
  2. 通常传值即可(拷贝只是两个指针),不需要传 const span&
  3. span<T> 可读写,span<const T> 只读。
  4. 它替代 const vector<T>& 做只读参数,接口更泛化且不绑定容器类型。

小结

std::span 让"传一段连续数组"的接口变得通用而轻量。遇到只读数组参数时,优先用 span<const T> 而不是 const vector<T>&