如何无内存分配从std::vector<std::vector<T>>创建std::span<std::span<T>>
从std::vector<std::vector>无内存分配创建std::span<std::span>的可行性
直接创建std::span<std::span<T>>是不可行的,核心原因是:std::span<std::span<T>>要求底层是连续存储的std::span<T>对象,但原二维vector的元素是std::vector<T>——这两种类型的内存布局完全不同,没办法直接在原内存上“投射”出连续的std::span<T>序列。
为什么你的尝试行不通
- 用
std::vector<std::span<T>>中转:必然需要内存分配,因为这个vector要存储一个个独立的std::span<T>小对象,它们需要连续的内存空间来存放。 - 先创建
std::span<std::vector<T>>:这个span指向的是原vector中的std::vector<T>元素,但std::vector<T>和std::span<T>类型不兼容,没法直接转换成std::span<std::span<T>>——两者的内存结构、对象大小都存在差异。
无内存分配的替代方案
如果你的核心需求是无内存分配地以二维“span-like”方式访问原数据,可以用C++20的范围视图实现:
#include <vector> #include <span> #include <ranges> template<typename T> void process_data(std::vector<std::vector<T>>& vv) { // 用transform视图把每个vector转换成span,全程无内存分配 auto span_view = vv | std::views::transform([](std::vector<T>& vec) -> std::span<T> { return vec; }); // 像使用二维span一样遍历操作 for (std::span<T> row : span_view) { for (T& elem : row) { // 对元素执行业务操作 } } }
这个视图完全基于原数据的引用,不需要分配任何堆内存,用法和std::span<std::span<T>>几乎一致。
必须用std::span<std::span>的情况
如果业务逻辑强制要求std::span<std::span<T>>类型,那无法避免内存分配——你必须先创建一个连续的std::span<T>序列,再用这个序列构造外层span:
std::vector<std::vector<T>> vv; // 分配内存存储span数组 std::vector<std::span<T>> span_vec; span_vec.reserve(vv.size()); for (auto& vec : vv) { span_vec.emplace_back(vec); } // 基于span_vec构造外层span std::span<std::span<T>> ss(span_vec);
内容的提问来源于stack exchange,提问作者jjcasmar
相关产品推荐
相关产品推荐

