如何迭代 mdspan?

ein*_*ica 7 c++ iteration ranged-loops c++23 mdspan

因此,我决定使用mdspan普通跨度 + 元素访问函数的组合,而不是简单的组合。但是 - 我想对 mdspan 做的一件明显的事情是迭代它的元素。这就是我用一维跨度来实现的方法:

std::vector vec = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 };
auto sp = std::span(vec.data(), 12);
for (auto x : sp) {
    std::cout << x << ' ';
}
std::cout << '\n';
Run Code Online (Sandbox Code Playgroud)

...但不适用于mdspan's (使用Kokkos 实现):

std::vector vec = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 };
auto ms = std::mdspan(vec.data(), 12);
for (auto x : ms) {
    std::cout << x << ' ';
}
std::cout << '\n';
Run Code Online (Sandbox Code Playgroud)

在 GodBolt(使用 GCC 主干)中尝试上述操作,我得到

<source>:10:19: error: 'begin' was not declared in this scope
   10 |     for (auto x : ms) {
      |                   ^~
Run Code Online (Sandbox Code Playgroud)

所以,看起来 mdspan 不是范围 - 即使它们是一维的(我什至希望迭代 2D 或 3D 跨度......)。怎么会?我该如何迭代它们?

ein*_*ica 2

mdspan看来你需要像普通的 C 数组一样迭代:

std::vector vec = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 };
auto ms = std::experimental::mdspan(vec.data(), 12);
for (auto i : std::views::iota(0uz, ms.extent(0))) {
    std::cout << ms[i] << ' ';
}
std::cout << '\n';
Run Code Online (Sandbox Code Playgroud)

...多维跨度也是如此 - 就像多维 C 数组一样,但具有多参数operator[]

std::vector vec = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 };
auto ms = std::experimental::mdspan(vec.data(), 2, 6);
for (auto r : std::views::iota(0uz, ms.extent(0))) {
    for (auto c : std::views::iota(0uz, ms.extent(1))) {
        std::cout << ms[r, c] << ' ';
        // ... and note that ms[r][c] won't work! :-(
    }
    std::cout << '\n';
}
Run Code Online (Sandbox Code Playgroud)

请参阅工作中的第二个示例:GodBolt

现在,我不知道为什么你不能直接迭代 - 因为mdspan's 肯定可以变得可迭代。也许这个想法是为了强调如何不保证内存中的顺序?我想知道。