C++23是否原生支持可复用多维索引对象?mdspan能否实现?
C++23 复用多维索引对象的实现方案
核心结论
C++23标准库并未原生提供可直接复用的多维索引对象,但通过自定义索引结构体+重载operator[],无论是使用mdspan还是原生嵌套std::array,都能轻松实现你需要的a[idx]、b[idx]式访问。
方案1:配合mdspan实现
mdspan本身不自带预定义的多维索引类型,但可以通过重载mdspan的operator[]来支持自定义索引对象:
#include <mdspan> #include <array> // 自定义多维索引结构体 struct Index { size_t i, j, k; }; // 给mdspan重载operator[],接受Index参数 template<class T, class Extents, class Layout, class Accessor> auto& operator[](std::mdspan<T, Extents, Layout, Accessor> span, const Index& idx) { return span[idx.i, idx.j, idx.k]; } // const版本重载,支持只读访问 template<class T, class Extents, class Layout, class Accessor> const auto& operator[](const std::mdspan<T, Extents, Layout, Accessor> span, const Index& idx) { return span[idx.i, idx.j, idx.k]; } // 使用示例 int main() { constexpr size_t N = 10, M = 10, L = 10; std::array<std::array<std::array<int, L>, M>, N> a{}; std::array<std::array<std::array<double, L>, M>, N> b{}; // 用mdspan包装原生数组 auto a_span = std::mdspan(a.data(), N, M, L); auto b_span = std::mdspan(b.data(), N, M, L); Index idx{3, 5, 2}; a_span[idx] = 42; b_span[idx] = 3.14; doSomething(a_span[idx], b_span[idx]); }
方案2:直接给嵌套std::array重载operator[]
如果不想引入mdspan,直接给三层嵌套的std::array重载operator[]即可:
#include <array> struct Index { size_t i, j, k; }; // 非const版本,支持读写 template<size_t N, size_t M, size_t L, class T> auto& operator[](std::array<std::array<std::array<T, L>, M>, N>& arr, const Index& idx) { return arr[idx.i][idx.j][idx.k]; } // const版本,支持只读 template<size_t N, size_t M, size_t L, class T> const auto& operator[](const std::array<std::array<std::array<T, L>, M>, N>& arr, const Index& idx) { return arr[idx.i][idx.j][idx.k]; } // 使用示例 int main() { constexpr size_t N = 10, M = 10, L = 10; std::array<std::array<std::array<int, L>, M>, N> a{}; std::array<std::array<std::array<double, L>, M>, N> b{}; Index idx{3, 5, 2}; a[idx] = 42; b[idx] = 3.14; doSomething(a[idx], b[idx]); }
补充说明
这两种方案的实现成本极低,代码简洁且符合C++23的语法规范,完全满足你复用多维索引、同时保持数组连续存储的需求。不需要依赖额外库,仅用标准库特性即可完成。
内容的提问来源于stack exchange,提问作者user122049
相关产品推荐
相关产品推荐

