如何将std::mdspan的一行转换为std::span?Kokkos实现咨询
关于mdspan转std::span的问题解答
目前不管是C++23标准中的std::mdspan,还是Kokkos的参考实现,确实没有提供直接将二维mdspan的一行转为std::span的成员函数或标准库自由函数,你并没有遗漏相关方法。
为什么直接赋值不行?
mdspan::operator[]返回的是一个多维切片视图(比如二维mdspan取一行后得到的是一维mdspan),而非std::span。虽然两者都是非拥有式数据视图,但mdspan的切片视图会保留原容器的布局映射信息,类型上和std::span不兼容,因此无法直接赋值转换。
可行的解决方案
1. 基于一维mdspan切片构造span
先通过operator[]拿到目标行的一维mdspan视图,再用它的data()和extent()构造std::span,这种方式不需要关心布局,更安全:
float* data = ...; std::mdspan matrix(data, 2, 5); auto row_view = matrix[0]; // 一维mdspan<float, std::dynamic_extent> std::span<float> vector(row_view.data(), row_view.extent(0));
2. 直接通过原始指针计算构造
如果知道mdspan的布局(比如默认的行优先layout_right),可以直接计算行的起始地址和长度:
// 行优先布局下,每行的起始偏移是 row_idx * 列数 std::span<float> vector(matrix.data() + 0 * matrix.extent(1), matrix.extent(1));
如果是列优先layout_left,则起始偏移就是row_idx,每行元素连续:
std::span<float> vector(matrix.data() + 0, matrix.extent(1));
3. 封装通用工具函数
如果需要适配不同布局,可以写个模板函数自动处理:
#include <mdspan> #include <span> template <typename MdSpan> auto mdspan_row_to_span(MdSpan&& md, std::size_t row_idx) -> std::span<typename MdSpan::value_type> { using value_type = typename MdSpan::value_type; auto row_view = md[row_idx]; return std::span<value_type>(row_view.data(), row_view.extent(0)); } // 使用示例 // auto vector = mdspan_row_to_span(matrix, 0);
补充说明
目前C++23标准中没有定义mdspan和std::span的直接转换接口,后续标准修订可能会考虑补充这类便捷转换,但现阶段只能通过上述手动方式实现。
内容的提问来源于stack exchange,提问作者PluginPenguin
相关产品推荐
相关产品推荐

