How to define a static constexpr matrix in c++14?

牧云@^-^@ 提交于 2019-12-11 07:48:53

问题


I am currently using C++14. I would like to define a Matrix class which I can use for defining runtime matrices, but also constexpr matrices. I also would like to define static constexpr matrices based on such a class.

I consider this as a starting point for the Matrix class. Then I would like to write something as:

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

so that staticmat is constexpr and unique, being static.

However, in order to initialise this, I would need a constexpr array or a constexpr initialiser list (not implemented in the link I posted, but not much would change). So I could write something like:

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

This would be ugly because I have to define two things just for one, but, if it worked, I could accept it. Unfortunately the compiler says unknown type name 'staticmattmp'.

How can I solve this, maybe in an elegant way?


回答1:


How can I solve this, maybe in an elegant way?

I don't know if it's elegant but... with a little work...

First of all, define the following using

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

Next re-declare (declare only; not define) Matrix as follows

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

Now declare your Matrix as a class partial specialization adding a constructor that receive NR*NC elements of type T and use them to initialize the internal 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
 };

But don't forget to declare as default the destructor (maybe also constructor and operator=()).

The following is a full compiling C++14 example

#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};
 }


来源:https://stackoverflow.com/questions/57012758/how-to-define-a-static-constexpr-matrix-in-c14

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!