使用 std::span视图容器

发布于:2025-06-08 ⋅ 阅读:(14) ⋅ 点赞:(0)

使用 std::span 视图容器

std::span 是 C++20 引入的一个轻量级非拥有(non-owning)视图容器,用于表示连续内存序列的视图。它不管理内存,只是提供对现有连续内存的安全访问接口。

基本用法

1. 包含头文件

#include <span>

2. 创建 span

// 从数组创建
int arr[] = {1, 2, 3, 4, 5};
std::span<int> s1(arr);

// 从 vector 创建
std::vector<int> vec = {1, 2, 3, 4, 5};
std::span<int> s2(vec);

// 从指针和大小创建
int* ptr = vec.data();
std::span<int> s3(ptr, vec.size());

3. 访问元素

std::span<int> s = /*...*/;

// 使用下标
int first = s[0];

// 使用 front() 和 back()
int first = s.front();
int last = s.back();

// 使用迭代器
for (auto it = s.begin(); it != s.end(); ++it) {
    // 处理 *it
}

// 范围 for 循环
for (int val : s) {
    // 处理 val
}

4. 子视图操作

std::span<int> s = /*...*/;

// 获取前 N 个元素
auto first3 = s.first(3);

// 获取后 N 个元素
auto last2 = s.last(2);

// 获取子范围 [offset, offset + count)
auto sub = s.subspan(1, 3);  // 从索引1开始,取3个元素

5. 其他常用操作

std::span<int> s = /*...*/;

// 获取大小
size_t size = s.size();

// 检查是否为空
bool empty = s.empty();

// 获取底层数据的指针
int* data = s.data();

// 获取字节大小
size_t bytes = s.size_bytes();

高级用法

1. 固定大小的 span

// 固定大小为5的span
std::span<int, 5> fixed_span(arr);

// 固定大小的span可以在编译期检查越界
// fixed_span[5] = 10;  // 编译错误

2. 与标准算法一起使用

std::vector<int> vec = {5, 3, 1, 4, 2};
std::span<int> s(vec);

// 排序
std::sort(s.begin(), s.end());

// 查找
auto it = std::find(s.begin(), s.end(), 3);

3. 作为函数参数

void process_data(std::span<const int> data) {
    // 只读访问data
}

void modify_data(std::span<int> data) {
    // 可修改访问data
}

int main() {
    std::vector<int> vec = {1, 2, 3};
    process_data(vec);
    modify_data(vec);
}

注意事项

  1. std::span 不拥有其元素,它只是视图
  2. 确保 std::span 的生命周期不超过底层数据
  3. 对于只读访问,使用 std::span<const T>
  4. 固定大小的 span 可以提供更好的编译时检查

std::span 是替代原始指针和大小对的一种更安全的方式,特别适合在函数间传递数组或连续容器数据。