提问人:Astor 提问时间:9/28/2023 最后编辑:Astor 更新时间:9/29/2023 访问量:171
C++23(或更高版本)使用索引向量提取数组元素的简洁方法?
C++23 (or later) succinct way to extract elements of an array using an index vector?
问:
我一直在研究使用最新标准对阵列进行切片的新方法,但这有点让人不知所措,我有一个问题。
有没有新的、简洁的方法,通过新的 C++23 添加到 、 、 甚至即将到来的 , ,使用带有要提取索引的向量将 an 的元素提取到另一个容器中?ranges
views
mdspan
submdspan
mdarray
mdspan
我必须事先知道它们的大小,但是,索引只有在运行时才能知道,因此我可以使用临时类型或其他容器。std::array
std::vector
下面是一个 godbolt 示例,转载如下
#include <iostream>
#include <array>
#include <vector>
#include <https://raw.githubusercontent.com/kokkos/mdspan/single-header/mdspan.hpp>
int main()
{
constexpr std::size_t pDeg = 16 ;
std::array<std::size_t,pDeg*pDeg> arr;
for (std::size_t i=0;i<arr.size();i++)
arr[i] = i ;
auto md = std::mdspan<std::size_t,std::extents<std::size_t,pDeg,pDeg>>(arr.data());
std::vector<std::size_t> ind1 = {1,5,6,7,8,9,4,5};
std::vector<std::size_t> ind2 = {14,11,12,13,11,1,5,6};
}
我实现了对矩阵进行操作的函数:、等multiply()
add()
我想写矩阵代数表达式,比如
auto result = add(multiply(md[ind1,:],md[:,ind2]),md[ind1,ind2]);
其中 是包含第 1、5、6、7、8、9、4、5 行的子矩阵,包含第 14、11、12、13、11、1、5、6 列,并且是包含由 和 分别给出的行和列的所有组合的 8×8 子矩阵(请注意,索引可以重复)。md[ind1,:]
md
md[:,ind2]
md
md[ind1,ind2]
md
ind1
ind2
或类似的东西
auto result = add(multiply(md.extract<0>(ind1),md.extract<1>(ind2)),md.extract<0,1>(ind1,ind2));
其中总是一个我知道编译时的大小。result
std::array
这些方法不一定是我建议的方法,但它们需要采用一种简短的符号,因为会有许多矩阵代数运算。
答: 暂无答案
评论
md[ind1, :]
md.extract<0>(ind1)
mdarray
必须等到 C++26,现在还远远不能使用。尝试避免它们,并且有范围适配器 + 算法。mdspan
std::view
std::ranges
ranges::copy(ranges::fold_left_first(views::zip_transform(multiplies<size_t>{}, r1, r2), plus<size_t>{}), begin(arr));
:
可能是“此维度上的所有元素”的 Matlab 表示法,但您将无法在 C++ 中以这种方式使用它。C++ 运算符重载不允许更改语法,只能更改行为。operator[]
md[{ind1, ind2}]