强制列表初始化矩阵的大小

Force list initialization size of a matrix

我设计了一个矩阵class。现在我想通过 list

初始化
Matrix3D m2{{1,2,3},{4,5,6},{7,8,9}};

而不是

Matrix3D m1(1,2,3,4,5,6,7,8,9);

我添加了一个静态断言来强制矩阵的大小,但它不起作用。

构造函数应该怎么修改?

#include <iostream>
using namespace std;

class Matrix3D
{
    int a11;
    int a12;
    int a13;
    int a21;
    int a22;
    int a23;
    int a31;
    int a32;
    int a33;

public:
    Matrix3D(
        int a11,
        int a12,
        int a13,
        int a21,
        int a22,
        int a23,
        int a31,
        int a32,
        int a33):
        a11(a11),
        a12(a12),
        a13(a13),
        a21(a21),
        a22(a22),
        a23(a23),
        a31(a31),
        a32(a32),
        a33(a33)        
    {

    }

    Matrix3D(std::initializer_list<std::initializer_list<double>> listlist);

};

Matrix3D::Matrix3D(std::initializer_list<std::initializer_list<double>> listlist)
{
    constexpr int rows = (int)(listlist.begin()).size();
    constexpr int cols = (int)listlist.size();
    static_assert(rows == 3, "");
    static_assert(cols == 3, "");

    a11=(listlist.begin()+0)[0];
    a12=(listlist.begin()+0)[1];
    a13=(listlist.begin()+0)[2];
    a21=(listlist.begin()+1)[0];
    a22=(listlist.begin()+1)[1];
    a23=(listlist.begin()+1)[2];
    a31=(listlist.begin()+2)[0];
    a32=(listlist.begin()+2)[1];
    a33=(listlist.begin()+2)[2];
}

int main() {
    Matrix3D m1(1,2,3,4,5,6,7,8,9);
    Matrix3D m2{{1,2,3},{4,5,6},{7,8,9}};
    return 0;
}

I have added a static assert to force the size of the matrix which does not work.

不幸的是,对于您的情况,std::initializer_list<Elem> 是为可变数量的元素设计的,这就是为什么在一般情况下您不能静态地说明其大小的原因。它的 size 成员是 constexpr 这一事实是一个转移注意力的问题:

constexpr std::initializer_list<int> constant_expr = { 0, 2, 4, 6 };
// this is what a constexpr size member makes possible
static_assert( constant_expr.size() == 4 );

std::initializer_list<int> non_constant_expr = { 1, 3, 5 };
// this can't work
//static_assert( non_constant_expr.size() == 3 );

函数参数不是常量表达式。

相反,您最好使用具有静态已知元素数量的类型。数组引用可以满足您的需求:

class Matrix3D {
    using index_type = int;
    static constexpr index_type cols = 3;
    using row_arg_type = int[cols];

public:
    Matrix3D(row_arg_type const& row0, row_arg_type const& row1, row_arg_type const& row2);

    // rest of class omitted
};

// number of rows and row width are statically enforced
Matrix3D m = { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 } };

Coliru demo