【问题标题】:initialize double nested std::array from variadic template array reference constructor从可变参数模板数组引用构造函数初始化双嵌套 std::array
【发布时间】:2021-03-26 08:12:01
【问题描述】:

问题

我有一个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;
};

问题

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

【问题讨论】:

  • 我们应该如何确定N?只是那个包的大小?
  • 您在初始化列表中初始化成员,而不是在构造函数主体中。
  • 是的,就是包的大小。 N 和 M 在编译时是已知的。基本上所有尺寸(即矩阵尺寸)都是固定的,这应该更容易初始化......
  • 上帝在这里:godbolt.org/z/GP9369
  • 我不明白 const &amp;&amp; 在这里的用法。他们通常来apart

标签: c++ arrays constructor c++14 variadic-templates


【解决方案1】:

如果没有显示的约束比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

【讨论】:

    【解决方案2】:

    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 之前,我们可以从 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

    【讨论】:

    • 不幸的是我必须使用 c++14。但我尝试了to_array 的简化实现,效果很好
    猜你喜欢
    • 1970-01-01
    • 2022-01-22
    • 1970-01-01
    • 2014-02-27
    • 1970-01-01
    • 2016-07-14
    • 2015-12-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多