我有一个矩阵类的定义如下:
template <typename T, unsigned int N, unsigned int M>
class TMatrixNxM
{
public:
TMatrixNxM(T = T(0));
TMatrixNxM(const std::array<std::array<T, M>, N>&);
TMatrixNxM(std::initializer_list<std::initializer_list<T>>);
private:
std::array<std::array<T, M>, N> data;
};
现在,在使用矩阵的代码中,我有:
Math::Matrix3x3 b({{1, 2, 3}, {4, 5, 6}, {7, 8, 9}});
(注:
矩阵x3x3
是的typedef
TMatrixNxM<浮动,3,3>
而且,它位于
数学
命名空间)
直到现在,它仍然有效,因为我并不总是有那个数组构造函数,只有初始化器列表1。但是现在,编译器甚至没有完成编译
碰撞
! (我收到“停止工作”弹出窗口,我必须关闭它,我正在使用MS VS Express 2013)
如果我这样做:
Math::Matrix3x3 b = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
然后它工作得很好。这就是我
假定
:
当我这样做时,就不会有歧义,因为你只能调用
初始化程序列表
构造函数。对于第一种方法,编译器可能会感到困惑,因为
大堆
是一种聚合类型,这意味着初始化以双大括号开始,例如:{{…}},但由于我有一个初始值设定项列表,我必须使用双大括号。但这真的应该是一个问题吗,因为我从来没有做过双大括号,这些都是单大括号列表中的单大括号的列表吗?
这里到底发生了什么,我该如何解决这个问题?
感谢您抽出时间!
编辑
如果我让构造函数通过常量指针获取数组,编译器就不会崩溃了(因为我永远不会直接在构造函数调用中扑通数组,所以我有初始化器列表):
TMatrixNxM(const std::array<std::array<T, M>, N>*);
然而,有人能解释之前的实际问题吗?我的假设是正确的吗?
这里有一个最小的可编译(或者,好吧,不是)代码,可以用来测试:
#include <array>
#include <initializer_list>
template <typename T, unsigned int N, unsigned int M>
class TMatrixNxM
{
public:
TMatrixNxM(T = T(0));
TMatrixNxM(const std::array<std::array<T, M>, N>&);
TMatrixNxM(std::initializer_list<std::initializer_list<T>>);
private:
std::array<std::array<T, M>, N> data;
};
template <typename T, unsigned int N, unsigned int M>
TMatrixNxM<T, N, M>::TMatrixNxM(T par_value)
{
std::array<T, M> temp;
temp.fill(par_value);
data.fill(temp);
}
template <typename T, unsigned int N, unsigned int M>
TMatrixNxM<T, N, M>::TMatrixNxM(const std::array<std::array<T, M>, N> &par_values)
{
data = par_values;
}
template <typename T, unsigned int N, unsigned int M>
TMatrixNxM<T, N, M>::TMatrixNxM(std::initializer_list<std::initializer_list<T>> par_values)
{
int i = 0;
for(std::initializer_list<T> row : par_values)
{
int j = 0;
for(T value : row)
{
data[i][j] = value;
++j;
}
++i;
}
}
int main()
{
TMatrixNxM<float, 3, 3> b({{1, 2, 3}, {4, 5, 6}, {7, 8, 9}});
return 0;
}
如果用数组注释掉构造函数声明/定义,那么它应该可以很好地编译和执行。如前所述,我使用的是MS VS Express 2013的编译器。