强制列表初始化矩阵的大小
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 } };
我设计了一个矩阵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 } };