如何基于kokkos/mdspan参考实现创建constexpr std::experimental::mdarray?
实现constexpr std::experimental::mdarray的便捷方案
问题背景
尝试基于mdspan参考实现创建constexpr的std::experimental::mdarray时遇到两个问题:
- 直接使用默认模板参数的mdarray,哪怕指定静态扩展(如
extents<size_t,1,1>),底层也会用std::vector存储,导致constexpr初始化失败 - 手动指定
std::array作为存储容器虽然可行,但需要自行计算总元素数;且遇到动态扩展时必须切换回std::vector,这种容器类型的手动切换对混合动态/静态扩展的模板类很不友好
自定义解决方案
我实现了一个模板别名,自动根据扩展类型选择合适的存储容器:
constexpr auto statistics_number_to_extent_size(const auto statistics_number) { assert(statistics_number >= 0); return statistics_number < std::numeric_limits<decltype(statistics_number)>::max() ? statistics_number : std::dynamic_extent; } template <typename T, typename L = std::experimental::layout_right, auto... Ns> using ConstExprMdArray = std::experimental::mdarray< T, std::experimental::extents<std::size_t, statistics_number_to_extent_size(Ns)...>, L, std::conditional_t<(... || (Ns >= std::numeric_limits<decltype(Ns)>::max())), std::vector<T>, std::array<T, (... * Ns)>>>; // 使用示例 ConstExprMdArray<float, std::experimental::layout_right, 1, 1> test_array;
该方案的核心逻辑:
- 通过
statistics_number_to_extent_size将标记为“最大值”的参数转换为std::dynamic_extent,用于表示动态维度 - 利用折叠表达式判断是否存在动态维度:只要有一个维度是动态的,就用
std::vector;否则用std::array并自动计算总大小
疑问
虽然自定义方案能解决问题,但我认为应该有更便捷的默认实现方式,不需要用户手动处理容器类型的条件选择。
内容的提问来源于stack exchange,提问作者Torsten Knodt
相关产品推荐
相关产品推荐

