C++20 span

Cindy ·
更新时间:2024-09-20
· 915 次阅读

C++20的span01 范围检查:span02 span demo 01 范围检查:span

span是对象的连续序列上的无所有权视图。1

类模板 span 所描述的对象能指代对象的相接序列,序列的首元素在零位置。 span 能拥有静态长度,该情况下序列中的元素数已知并编码于类型中,或拥有动态长度。
典型实现只保有二个成员:指向 T 的指针和大小。2

到2020年1月16日前,有3个span的开源版本。
微软实现了一个版本的span3。微软版gsl目前有9个头文件。

独立头文件的兼容C ++ 11及更高版本的span实现。4

span lite:适用于C ++ 98,C ++ 11和更高版本的C ++ 20跨度的单文件标头版本。5

span用来做范围检查。提供对一个连续元素序列(主要指内置数组)的访问能力。元素可用很多方式存储,包括存储在vector和内置数组中。类似于指针,一个span不拥有它指向的字符。在这一点上,它很像string_view和STL的迭代器对。
std::span可能采用合约来控制对范围错误的响应。span的范围检查几乎无额外性能代价。6

span能很好的解决内置数组退化和越界访问的问题。7

02 span demo

https://github.com/5455945/cpp_demo/blob/master/C%2B%2B20/span/span.cpp

#include // 这里的gsl::span是微软的一个开源实现 // https://github.com/microsoft/GSL/tree/master/include/gsl #include using namespace std; // 《C++语言导论》 P147 13.3 范围检查:span void fpn(int* p, int n) { // p可以是一个内置数组 for (int i = 0; i 100,Run-Time Check Failure #2 - Stack around the variable 'a' was corrupted.) } void fs(gsl::span p) { for (auto& x : p) { x = 2; } } void use_span(int x) { int a[100]; fs(a); // 隐式创建一个span{a, 100} //fs({ a, 1000 }); // 错误:期待一个sapn //fs({ a + 10, 100 }); // 在fs中发生范围错误,(Run-Time Check Failure #2 - Stack around the variable 'a' was corrupted.) //fs({ a, x }); // 明显可疑,(x>100,Run-Time Check Failure #2 - Stack around the variable 'a' was corrupted.) } // C++核心准则边译边学-X.4:使用span解决数组退化和越界访问 // https://blog.csdn.net/craftsman1970/article/details/103217292 void traditional_array(int buffer[], size_t size) { cout << "size=" << size << endl; for (int i = 0; i < int(size); ++i) { buffer[i] = i; } buffer[0] = int(size * 2); //buffer[size * 2] = int(size * 4); // 传统数组越界访问 } void span_array(gsl::span buffer) { cout << "size=" << buffer.size() << endl; int value = 0; for (auto it = buffer.begin(); it != buffer.end(); it++) { *it = value++; } buffer[0] = value++; //buffer[buffer.size() * 2] = value++; // span会触发断言 } int main() { int x = 105; use(x); use_span(x); int data[10]; // 内置数组 for (size_t i = 0; i < sizeof(data) / sizeof(data[0]); ++i) { data[i] = 0; } // 使用数组传递参数 traditional_array(data, 5); // 使用span传递参数 span_array(data); gsl::span sdata = data; for (auto v : sdata) { std::cout << v << ", "; } std::cout << std::endl; return 0; }

标准库头文件span ↩︎

std::span ↩︎

准则支持库 ↩︎

为旧版编译器实现C ++ 20的单独头文件的span ↩︎

span lite,适用于C++98,及更高版本的单独头文件实现的span ↩︎

《C++语言导论》第二版 P147 ↩︎

C++核心准则边译边学-X.4:使用span解决数组退化和越界访问 ↩︎


作者:longji



c+ C++ span

需要 登录 后方可回复, 如果你还没有账号请 注册新账号