为什么编译器抱怨这不是constexpr?

Big*_*ion 8 c++ visual-c++ constexpr c++11

我正在尝试学习如何在实践中使用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_{};
};
Run Code Online (Sandbox Code Playgroud)

我们的想法是拥有一个简单的Matrix类,我可以将它用于小矩阵,以便在编译时评估Matrix表达式(请注意,我还没有实现常用的Matrix运算符来进行加法和乘法).

当我尝试按如下方式初始化Matrix实例时:

constexpr std::array<double, 4> a = {1,1,1,1};
constexpr Matrix<double, 2, 2> m(a);
Run Code Online (Sandbox Code Playgroud)

我从编译器(MS Visual C++ 14)收到以下错误:

error: C2127: 'm': illegal initialization of 'constexpr' entity with a non-constant expression
Run Code Online (Sandbox Code Playgroud)

请注意我做错了什么...任何帮助使这项工作将不胜感激!

Pio*_*cki 13

[basic.types]/p10指出:

类型是文字类型,如果它是:

  • 可能是合格的void; 要么

  • 标量类型; 要么

  • 参考类型; 要么

  • 一个文字类型的数组; 要么

  • 可能具有cv限定的类类型(Clause [class]),它具有以下所有属性:

    • 它有一个简单的析构函数,

    • 它是一个闭包类型([expr.prim.lambda]),一个聚合类型([dcl.init.aggr]),或者至少有一个constexpr构造函数或构造函数模板(可能是继承的([namespace.udecl])一个基类),它不是复制或移动构造函数,

    • 如果它是一个联合,它的至少一个非静态数据成员是非易失性文字类型,和

    • 如果它不是联合,则其所有非静态数据成员和基类都是非易失性文字类型.

其中[class.dtor]/p5说:

如果不是用户提供的析构函数是微不足道的,如果:

(5.4) - 析构函数不是virtual,

(5.5) - 同类的所有直接基类都有简单的析构函数

(5.6) - 对于类的所有类型(或其数组)的非静态数据成员,每个这样的类都有一个简单的析构函数.

否则,析构函数是非平凡的.

换句话说,要声明一个constexpr实例Matrix,它必须是文字类型,并且作为文字类型,它的析构函数必须是defaulted或者完全删除,所以:

~Matrix() = default;
Run Code Online (Sandbox Code Playgroud)

要么:

 

  • 我喜欢_or_.:-) (6认同)