如何在 C++14 中定义静态 constexpr 矩阵?
How to define a static constexpr matrix in c++14?
我目前正在使用 C++14。
我想定义一个 Matrix
class ,我可以用它来定义运行时矩阵,还有 constexpr 矩阵。我还想基于这样的 class 定义静态 constexpr 矩阵。
我认为 是 Matrix
class 的起点。
然后我想写一些东西:
static constexpr Matrix<double,2,2> staticmat{0.1,0.2,0.3,0.4};
所以 staticmat 是常量和唯一的,是静态的。
然而,为了初始化这个,我需要一个 constexpr
数组或一个 constexpr
初始化列表(在我发布的 link 中没有实现,但不会有太大变化).所以我可以这样写:
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'
.
我该如何解决这个问题,也许是一种优雅的方式?
How can I solve this, maybe in an elegant way?
我不知道它是否优雅但是...稍微工作一下...
首先定义如下using
template <typename T, std::size_t>
using getType = T;
下一个re-declare(仅声明;未定义)Matrix
如下
template <typename, std::size_t NR, std::size_t NC,
typename = std::make_index_sequence<NR*NC>>
class Matrix;
现在将您的 Matrix
声明为 class 部分特化,添加接收 NR*NC
类型 T
元素的构造函数并使用它们初始化内部 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};
}
我目前正在使用 C++14。
我想定义一个 Matrix
class ,我可以用它来定义运行时矩阵,还有 constexpr 矩阵。我还想基于这样的 class 定义静态 constexpr 矩阵。
我认为 Matrix
class 的起点。
然后我想写一些东西:
static constexpr Matrix<double,2,2> staticmat{0.1,0.2,0.3,0.4};
所以 staticmat 是常量和唯一的,是静态的。
然而,为了初始化这个,我需要一个 constexpr
数组或一个 constexpr
初始化列表(在我发布的 link 中没有实现,但不会有太大变化).所以我可以这样写:
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'
.
我该如何解决这个问题,也许是一种优雅的方式?
How can I solve this, maybe in an elegant way?
我不知道它是否优雅但是...稍微工作一下...
首先定义如下using
template <typename T, std::size_t>
using getType = T;
下一个re-declare(仅声明;未定义)Matrix
如下
template <typename, std::size_t NR, std::size_t NC,
typename = std::make_index_sequence<NR*NC>>
class Matrix;
现在将您的 Matrix
声明为 class 部分特化,添加接收 NR*NC
类型 T
元素的构造函数并使用它们初始化内部 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};
}