文档目录

string_view 是"字符的 view";span 是"任意类型的 view"。

解决什么问题?

// ❌ 传统函数签名:零散的指针+长度
void process(const float* data, size_t count);
// 调用者容易传错:process(arr, 1000) // 如果 arr 只有 500 个元素呢?

// ✅ span:长度自带
void process(std::span<const float> data);
// 调用者:process(arr); // 自动推导长度
// 或者:process(vec);   // vector 也能直接传

span 的内存结构:

span<float> s(vec);
栈上占用 16 字节(64 位):
+──────────────────+──────────────────+
| ptr (8字节)       | size (8字节)      |
| 指向 vec.data()   | vec.size()        |
+──────────────────+──────────────────+

没有任何堆分配,不拥有数据,只是一个指针 + 长度。

什么时候用?

// 1. 替代 (T* data, size_t len) —— 最常见的场景
void process(std::span<const int> data);

// 2. 需要同时支持 vector / array / C 数组的函数
void sort_all(std::span<int> data) {
    std::sort(data.begin(), data.end());
}

std::vector<int> v = {3, 1, 4, 1, 5};
int arr[] = {2, 7, 1, 8};
sort_all(v);    // ✅ vector
sort_all(arr);  // ✅ C 数组(自动推导长度为 4)

// 3. 子范围操作
auto first_half = s.first(s.size() / 2);  // 取前半,不拷贝
auto second_half = s.last(s.size() / 2);   // 取后半
auto middle = s.subspan(2, 5);             // 取 [2, 7)

和 string_view 完全一样的生命周期规则

delete 原始数组后,span 悬垂。