mdspan标准化后,C++中拥有多维数组的惯用方式是什么?
mdspan标准化后,C++中拥有多维数组的惯用方式是什么?
嘿,这个问题问到点子上了!之前咱们在C里搞多维数组,要么硬啃原生的多维C数组,那指针衰减的坑谁踩谁头疼;要么就得依赖第三方库来解决。但自从mdspan被纳入C标准之后,咱们终于有了原生标准的多维数组处理方案,现在主流的惯用方式都围绕它展开:
用mdspan包装现有内存,实现多维视图
不管是栈上的原生数组、堆上的动态数组,还是std::vector这类容器的内存,都能直接用mdspan来“套壳”,不用额外拷贝数据。比如你有一段连续存储的一维数据,想当成二维数组来用:#include <mdspan> #include <vector> int main() { // 存储3行4列数据的vector std::vector<int> data(12, 0); // 包装成3×4的二维视图,默认是行主序布局 std::mdspan<int, std::extents<std::size_t, 3, 4>> arr(data.data()); // 像原生多维数组一样直接访问 arr[1][2] = 42; return 0; }这种方式灵活度拉满,完全不改动原有的数据存储逻辑,只是给它加了个多维访问的入口。
动态维度的mdspan适配场景
如果编译时没法确定数组的维度大小,就用std::dextents来创建动态扩展的mdspan,运行时再指定维度:// 动态二维视图,维度在运行时传入 std::mdspan<int, std::dextents<std::size_t, 2>> dynamic_arr(data.data(), 5, 6);这种写法特别适合那些维度需要根据业务逻辑动态计算的场景。
搭配标准算法简化遍历逻辑
mdspan支持C++20的范围(ranges)接口,所以能直接和标准算法配合使用,不用再写嵌套循环遭罪:#include <algorithm> #include <iostream> // 遍历整个多维数组并打印 std::ranges::for_each(arr, [](int val) { std::cout << val << " "; });是不是比自己写两层for循环清爽多了?
替代原生多维数组避免指针衰减坑
原来的原生多维数组(比如int arr[3][4])传参时会退化成指针,直接丢失维度信息,用mdspan传参就完全没这个问题,维度信息会被完整保留:void process_2d(std::mdspan<int, std::extents<std::size_t, 3, 4>> arr) { // 在这里完全明确知道数组是3×4的,不会有任何歧义 arr[0][0] = 10; }
最后得提一句:mdspan是视图类型,它不拥有数据的所有权,所以一定要保证原数据的生命周期比mdspan长,不然就会出现悬空访问的问题哦!
内容来源于stack exchange
相关产品推荐
相关产品推荐

