从variadic模板数组引用构造函数初始化双嵌套std::数组



问题

我有一个能做一些数学的Matrix班。它将数据作为变量保存在一个双嵌套的std::array中。我有一个构造函数,它将数组引用作为可变模板。我这样做是为了更容易地添加一些SFINAE(此处省略(。

#include <array>
template <std::size_t N, std::size_t M, typename T>
class Matrix{
public:
template <typename... TArgs>
Matrix(TArgs const(&&... rows)[M]) {
// ??
}
// ...
private:
std::array<std::array<T,M>, N> data;
};

问题

如何初始化构造函数中的双嵌套数组?

使用未显示的约束条件sizeof..(TArgs) == N和类型为T,您可以将行地址存储在数组指针中,然后正常工作

template <typename... TArgs>
Matrix(TArgs const(&&... rows)[M]) {
using Arr = const T (*)[M];
const Arr args[N] = {&rows...}; // or const T (*args[N])[M] = {&rows...};
for (std::size_t i = 0; i != N; ++i) {
for (std::size_t j = 0; j != M; ++j) {
data[i][j] = (*args[i])[j];
}
}
}

演示

有了std::to_array,它将成为C++20的一部分,我们可以简单地写:

template<std::size_t N, std::size_t M, typename T>
class Matrix {
public:
template<typename... Args>
Matrix(const Args(&... rows)[M]) : data{std::to_array(rows)...}
{}
private:
std::array<std::array<T, M>, N> data;
};

在C++20之前,我们可以从这里复制粘贴to_array实现,这将为该解决方案添加更多的行。

简化实施:

template<std::size_t N, typename T, std::size_t... is>
std::array<T, N> to_array_impl(const T(& arr)[N], std::index_sequence<is...>) {
return std::array<T, N>{arr[is]...};
}
template<std::size_t N, typename T>
std::array<T, N> to_array(const T(& arr)[N]) {
return to_array_impl(arr, std::make_index_sequence<N>{});
}

通过成员列表初始化,您也可以初始化const data

最新更新