当年写 C。
函数参数最常见的形态是。
T* 加一个长度。
简单。
高效。
但也很脆。
因为你只要把长度传错。
就会读到你不该读的地方。
当年:指针和长度靠约定绑定
int sum(const int* p, int n);
这个接口看起来很正常。
但它其实在赌。
调用者一定会把 p 和 n 配对。
线上啪一下:长度传大了,偶尔越界,偶尔不炸
你写一个小项目。
把数组的一段求和。
int a[3] = {1, 2, 3};
int s = sum(a, 10);
这段代码。
在 C 里甚至能跑。
你可能在线上某次请求。
突然算出一个离谱的 s。
然后你开始怀疑内存。
怀疑线程。
最后才发现。
就是参数传错。
C++20:std::span
std::span 把“指针 + 长度”。
收进一个类型。
你把它当成“数组视图”。
它不拥有内存。
它只是描述一段连续内存。
用 span 改写接口
#include <span>
int sum(std::span<const int> a) {
int s = 0;
for (int x : a) s += x;
return s;
}
现在调用方很难传错。
因为它要先构造一个 span。
你传数组。
长度是自动带上的。
int a[3] = {1, 2, 3};
int s = sum(a);
你刚学 C++ 会卡:span 会不会拷贝数据
不会。
它只是两个字段。
一个指针。
一个长度。
它只是把这对老搭档。
打包得更像一个参数。
关键结论
span 省的不是性能。
是“传参出错”的概率。
小结
你可以继续用指针。
但当你要传一段连续内存。
span 更像一个靠谱的接口。