从可变模板数组引用构造函数初始化双嵌套 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];
        }
    }
}

Demo

有了 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