为什么编译器抱怨这不是一个 constexpr?
Why does the compiler complain about this not being a constexpr?
我正在努力学习更多有关如何在实践中使用 C++ 常量表达式的知识,并创建了以下 Matrix class 模板用于说明目的:
#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_{};
};
我的想法是拥有一个简单的矩阵 class,我可以将其用于小矩阵,以便在编译时计算矩阵表达式(请注意,我还没有实现常用的矩阵运算符来进行加法和乘法运算) .
当我尝试按如下方式初始化 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
请注意确定我做错了什么...非常感谢任何有助于完成这项工作的帮助!
A type is a literal type if it is:
possibly cv-qualified 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:
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,
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.
其中 [class.dtor]/p5 表示:
A destructor is trivial if it is not user-provided and if:
(5.4) — the destructor is not virtual
,
(5.5) — all of the direct base classes of its class have trivial destructors, and
(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.
Otherwise, the destructor is non-trivial.
换句话说,要声明 Matrix
的 constexpr
实例,它必须是文字类型,并且要成为文字类型,其析构函数必须是 default
ed ,或完全删除,因此:
~Matrix() = default;
或:
我正在努力学习更多有关如何在实践中使用 C++ 常量表达式的知识,并创建了以下 Matrix class 模板用于说明目的:
#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_{};
};
我的想法是拥有一个简单的矩阵 class,我可以将其用于小矩阵,以便在编译时计算矩阵表达式(请注意,我还没有实现常用的矩阵运算符来进行加法和乘法运算) .
当我尝试按如下方式初始化 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
请注意确定我做错了什么...非常感谢任何有助于完成这项工作的帮助!
A type is a literal type if it is:
possibly cv-qualified
void
; ora 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:
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,
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.
其中 [class.dtor]/p5 表示:
A destructor is trivial if it is not user-provided and if:
(5.4) — the destructor is not
virtual
,(5.5) — all of the direct base classes of its class have trivial destructors, and
(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.
Otherwise, the destructor is non-trivial.
换句话说,要声明 Matrix
的 constexpr
实例,它必须是文字类型,并且要成为文字类型,其析构函数必须是 default
ed ,或完全删除,因此:
~Matrix() = default;
或: