从可变模板数组引用构造函数初始化双嵌套 std::array
initialize double nested std::array from variadic template array reference constructor
问题
我有一个 Matrix
class 可以做一些数学运算。它将其数据作为变量保存在双重嵌套 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];
}
}
}
有了 C++20 的一部分 std::to_array
,我们可以简单地写成:
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 之前,我们可以从 here 复制粘贴 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
。
问题
我有一个 Matrix
class 可以做一些数学运算。它将其数据作为变量保存在双重嵌套 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];
}
}
}
有了 C++20 的一部分 std::to_array
,我们可以简单地写成:
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 之前,我们可以从 here 复制粘贴 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
。