问题
Problem
I have a Matrix
class that is able to do some math. It holds its data in a double nested std::array
as a variable. I have a constructor that takes an array reference as a variadic template. I did this so i could add some SFINAE more easily (omitted here).
#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;
};
Question
How can i initialize the double nested array inside the constructor?
回答1:
With the not shown constraint than sizeof..(TArgs) == N
and types are T
, you might store address of rows in array pointer and then work normally
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];
}
}
}
Demo
回答2:
With std::to_array
that would be part of C++20, we could simply write:
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;
};
Until C++20 we can copy-paste to_array
implementation from here, which will add a few more lines to this solution.
Simplified implementation:
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>{});
}
With member list initialization you would be able to initialize const data
, too.
来源:https://stackoverflow.com/questions/65310179/initialize-double-nested-stdarray-from-variadic-template-array-reference-const