【问题标题】:How to define a static constexpr matrix in c++14?如何在 c++14 中定义静态 constexpr 矩阵?
【发布时间】:2019-11-22 13:31:14
【问题描述】:

我目前正在使用 C++14。 我想定义一个 Matrix 类,我可以用它来定义运行时矩阵,也可以用来定义 constexpr 矩阵。我还想基于这样的类定义静态 constexpr 矩阵。

我认为thisMatrix 类的起点。 然后我想写一些东西:

static constexpr Matrix<double,2,2> staticmat{0.1,0.2,0.3,0.4};

因此 staticmat 是 constexpr 且唯一的,是静态的。

但是,为了初始化它,我需要一个 constexpr 数组或 constexpr 初始化列表(在我发布的链接中没有实现,但不会有太大变化)。所以我可以写这样的东西:

static constexpr std::array<double,4> staticmattmp{0.1,0.2,0.3,0.4};
static constexpr Matrix<double,2,2> staticmat(staticmattmp);

这会很难看,因为我必须为一个定义两件事,但是,如果它有效,我可以接受它。不幸的是编译器说unknown type name 'staticmattmp'

我怎样才能解决这个问题,也许以一种优雅的方式?

【问题讨论】:

    标签: matrix constructor static c++14 constexpr


    【解决方案1】:

    我怎样才能解决这个问题,也许以一种优雅的方式?

    我不知道它是不是很优雅,但是……有点工作……

    首先定义如下using

    template <typename T, std::size_t>
    using getType = T;
    

    接下来重新声明(只声明;不定义)Matrix如下

    template <typename, std::size_t NR, std::size_t NC,
              typename = std::make_index_sequence<NR*NC>>
    class Matrix;
    

    现在将您的Matrix 声明为类的部分特化,添加一个构造函数,该构造函数接收T 类型的NR*NC 元素并使用它们来初始化内部std::array

    template <typename T, std::size_t NR, std::size_t NC, std::size_t ... Is>
    class Matrix<T, NR, NC, std::index_sequence<Is...>>
     {
       public:
           using value_type = T;
    
          constexpr Matrix (getType<value_type, Is> ... vals)
             : values_{{vals...}}
           {}
    
          // other member and methods
     };
    

    但不要忘记将析构函数声明为default(也可以是构造函数和operator=())。

    以下是完整的编译C++14示例

    #include <array>
    #include <type_traits>
    
    template <typename T, std::size_t>
    using getType = T;
    
    template <typename, std::size_t NR, std::size_t NC,
              typename = std::make_index_sequence<NR*NC>>
    class Matrix;
    
    template <typename T, std::size_t NR, std::size_t NC, std::size_t ... Is>
    class Matrix<T, NR, NC, std::index_sequence<Is...>>
     {
       public:
          using value_type = T;
    
          constexpr Matrix (getType<value_type, Is> ... vals)
             : values_{{vals...}}
           {}
    
          constexpr Matrix (std::array<T, NR*NC> const & a)
             : values_{a}
           {}
    
          constexpr Matrix (std::array<T, NR*NC> && a)
             : values_{std::move(a)}
           {}
    
          constexpr Matrix () = default;
    
          ~Matrix() = default;
    
          constexpr Matrix (Matrix const &) = default;
          constexpr Matrix (Matrix &&) = default;
    
          constexpr Matrix & operator= (Matrix const &) = default;
          constexpr Matrix & operator= (Matrix &&) = default;
    
    
          constexpr T const & operator() (std::size_t r, std::size_t c) const
           { return values_[r*NC+c]; }
    
          T & operator() (std::size_t r, std::size_t c)
           { return values_[r*NC+c]; }
    
          constexpr std::size_t rows () const
           { return NR; }
    
          constexpr std::size_t columns () const
           { return NC; }
    
       private:
          std::array<T, NR*NC> values_{};
     };
    
    int main()
     {
       static constexpr Matrix<double,2,2> staticmat{0.1,0.2,0.3,0.4};
     }
    

    【讨论】:

    • 非常感谢。基本上我们需要定义 getType 来创建像“T...”这样的可变参数。此外,由于本例中的所有内容都在 constexpr 中,我们可以将编译时参数作为模板参数 (double,2,2),也可以作为构造函数参数。我说的对吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-01-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多