[英]Why does the compiler complain about this not being a constexpr?
I am trying to learn a bit more on how to use C++ constant expressions in practice and created the following Matrix class template for illustration purposes: 我正在尝试学习如何在实践中使用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_{};
};
The idea is to have a simple Matrix class, which I can use for small matrices to evaluate Matrix expressions at compile time (note that I have not yet implemented the usual Matrix operators for addition and multiplication). 我们的想法是拥有一个简单的Matrix类,我可以将它用于小矩阵,以便在编译时评估Matrix表达式(请注意,我还没有实现常用的Matrix运算符来进行加法和乘法)。
When I try to initialize a Matrix instance as follows: 当我尝试按如下方式初始化Matrix实例时:
constexpr std::array<double, 4> a = {1,1,1,1};
constexpr Matrix<double, 2, 2> m(a);
I am getting the following error from the compiler (MS Visual C++ 14): 我从编译器(MS Visual C ++ 14)收到以下错误:
error: C2127: 'm': illegal initialization of 'constexpr' entity with a non-constant expression
Note sure what I am doing wrong...any help to make this work would be greatly appreciated! 请注意我做错了什么...任何帮助使这项工作将不胜感激!
[basic.types]/p10 states that: [basic.types] / p10指出:
A type is a literal type if it is:
类型是文字类型,如果它是:
possibly cv-qualified
void
;可能是cv合格的
void
; or要么
a scalar type;
标量类型; or
要么
a reference type;
参考类型; or
要么
an array of literal type;
一个文字类型的数组; or
要么
a possibly cv-qualified class type (Clause [class] ) that has all of the following properties:
可能具有cv限定的类类型(Clause [class] ),它具有以下所有属性:
it has a trivial destructor,
它有一个简单的析构函数,
it is either a closure type ( [expr.prim.lambda] ), an aggregate type ( [dcl.init.aggr] ), or has at least one constexpr constructor or constructor template (possibly inherited ( [namespace.udecl] ) from a base class) that is not a copy or move constructor,
它是一个闭包类型( [expr.prim.lambda] ),一个聚合类型( [dcl.init.aggr] ),或者至少有一个constexpr构造函数或构造函数模板(可能是继承的( [namespace.udecl] )一个基类),它不是复制或移动构造函数,
if it is a union, at least one of its non-static data members is of non-volatile literal type, and
如果它是一个联合,它的至少一个非静态数据成员是非易失性文字类型,和
if it is not a union, all of its non-static data members and base classes are of non-volatile literal types.
如果它不是联合,则其所有非静态数据成员和基类都是非易失性文字类型。
where [class.dtor]/p5 says that: 其中[class.dtor] / p5说:
A destructor is trivial if it is not user-provided and if:
如果不是用户提供的析构函数是微不足道的,如果:
(5.4) — the destructor is not
virtual
,(5.4) - 析构函数不是
virtual
,(5.5) — all of the direct base classes of its class have trivial destructors, and
(5.5) - 同类的所有直接基类都有琐碎的析构函数
(5.6) — for all of the non-static data members of its class that are of class type (or array thereof), each such class has a trivial destructor.
(5.6) - 对于类的所有类型(或其数组)的非静态数据成员,每个这样的类都有一个简单的析构函数。
Otherwise, the destructor is non-trivial .
否则,析构函数是非平凡的 。
In other words, to declare a constexpr
instance of Matrix
, it must be a literal type, and to be a literal type, its destructor must be either default
ed, or removed altogether, so: 换句话说,要声明
Matrix
的constexpr
实例,它必须是文字类型,并且要作为文字类型,其析构函数必须是default
编辑或完全删除,因此:
~Matrix() = default;
or: 要么:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.