深入学习 std::span

深入学习 std::span 头文件:<span> 命名空间:std 编译器要求:C++20 起 一、设计动机:统一连续内存的访问接口 1.1 C++ 中连续内存的 N 种传参方式 在没有 span 之前,传递"一段连续内存"的方式五花八门: 1 2 3 4 5 6 7 8 9 10 11 12 13 // 方式1:C 风格——指针 + 长度(容易出错,长度可能传错) void process(const int* data, size_t len); // 方式2:模板——编译膨胀,每种容器实例化一份 template <typename Container> void process(const Container& c); // 方式3:特化 vector 引用——不接受 array 或 C 数组 void process(const std::vector<int>& v); // 方式4:迭代器对——语法啰嗦,不直观 template <typename Iter> void process(Iter begin, Iter end); 核心问题: 没有一种统一的、类型安全的方式说"我只需要一段连续内存的只读/可写视图"。 1.2 span 的解法 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 #include <span> #include <vector> #include <array> #include <cstdio> // ✅ 一个函数接受所有连续内存容器 void process(std::span<const int> data) { for (int val : data) { printf("%d ", val); } printf("\n"); } int main() { // span 能从任何连续内存容器隐式构造 std::vector<int> vec = {1, 2, 3, 4, 5}; std::array<int, 3> arr = {10, 20, 30}; int cArr[] = {100, 200, 300, 400}; process(vec); // vector → span:隐式转换 process(arr); // array → span:隐式转换 process(cArr); // C 数组 → span:隐式转换 process({vec.data() + 1, 3}); // 子区间:手动指定 {ptr, count} } 一句话总结:span 是连续内存的"通用视图"——不拥有数据、不分配内存、只是指针+长度的薄封装。 ...

May 25, 2022 · 10 min · 1921 words