我正在尝试学习如何在实践中使用C ++常量表达式,并创建以下Matrix类模板用于说明目的:
#include <array>
template <typename T, int numrows, int numcols>
class Matrix{
public:
using value_type = T;
constexpr Matrix() : {}
~Matrix(){}
constexpr Matrix(const std::array<T, numrows*numcols>& a) :
values_(a){}
constexpr Matrix(const Matrix& other) :
values_(other.values_){
}
constexpr const T& operator()(int row, int col) const {
return values_[row*numcols+col];
}
T& operator()(int row, int col){
return values_[row*numcols+col];
}
constexpr int rows() const {
return numrows;
}
constexpr int columns() const {
return numcols;
}
private:
std::array<T, numrows*numcols> values_{};
};
我的想法是有一个简单的Matrix类,我可以将它用于小矩阵,以便在编译时评估Matrix表达式(请注意,我还没有实现通常的Matrix运算符来进行加法和乘法)。
当我尝试按如下方式初始化Matrix实例时:
constexpr std::array<double, 4> a = {1,1,1,1};
constexpr Matrix<double, 2, 2> m(a);
我从编译器(MS Visual C ++ 14)收到以下错误:
error: C2127: 'm': illegal initialization of 'constexpr' entity with a non-constant expression
请注意确定我做错了什么......任何帮助我做这项工作都将不胜感激!
答案 0 :(得分:13)
类型是文字类型,如果它是:
可能是cv-qualified
void
;或标量类型;或
参考类型;或
一个文字类型的数组;或
可能具有cv资格的类类型(条款[class]),它具有以下所有属性:
它有一个简单的析构函数,
它是闭包类型([expr.prim.lambda]),聚合类型([dcl.init.aggr]),或者至少有一个constexpr构造函数或构造函数模板(可能是继承的([namespace.udecl]) )来自基类),它不是复制或移动构造函数,
如果它是一个联合,其至少一个非静态数据成员是非易失性文字类型,并且
如果它不是联合,则其所有非静态数据成员和基类都是非易失性文字类型。
如果析构函数不是用户提供的,并且如果:
,则析构函数很简单(5.4) - 析构函数不是
virtual
,(5.5) - 其类的所有直接基类都有简单的析构函数,并且
(5.6) - 对于类类的所有非静态数据成员(或其数组),每个都是这样的 class有一个简单的析构函数。
否则,析构函数非平凡。
换句话说,要声明constexpr
Matrix
实例,它必须是文字类型,并且作为文字类型,其析构函数必须是default
ed,或者完全删除,所以:
~Matrix() = default;
或: