问题
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