2012-03-20 3 views
2

私はC++でジェネリックな行列クラスを書いています。私は二次元二重配列から行列を初期化できるようにしたい。私はテンプレートを使用しているので、コンパイル時に行列サイズを知る必要があるので、指定されたサイズの配列だけをコンストラクタに渡すことができます。コードで表すと、これは次のとおりです。今固定長の多次元配列の引数

template<unsigned int M, unsigned int N> 
class Matrix { 
public: 
    Matrix(double (&values)[M][N]); 
} 

、ここで奇妙な部分が来る:

double arr [3][3] = { {1,2,3}, 
          {1,2,3}, 
          {1,2,3} }; 
    Matrix<3,3>* mat3x3p = new Matrix<3,3>(arr); 

しかし、匿名で配列を渡す時にコードが壊れている:等は次のコードは、魔法のように動作が期待

Matrix<3,3>* mat3x3p = new Matrix<3,3>({ {1,2,3}, 
             {1,2,3}, 
             {1,2,3} }); 

同じことが割り当てによる構築にも当てはまります。 正確なエラー・メッセージがある:C++標準の初期リスト当たり

+0

'Matrix(double(&values)[] [N]);' –

+0

これはうまくいきませんでした – Paranaix

+0

申し訳ありません、私の悪いです。 'Matrix(const double(&values)[M] [N]);は動作します。 –

答えて

2

これは、一時的に(への(左値)参照へのバインディングであり、許可されていません)。 constへの参照に変更すると、それはうまくいくでしょう - 配列の場合は、cv --qualifiersは配列自体ではなく要素型に適用されるため、少し変です。それにもかかわらず、あなたはその後、

Matrix<3, 3>({{ 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 }}) 

Matrix(const double (&values)[M][N]); 

を持っている場合は、リストの初期化のおかげでC++ 11で有効です。私はそれをC++ 03で動作させる方法を知らない。

+0

興味深いことに、const修飾子を追加するとコンストラクタの問題が解決されますが、割り当てはまだできません – Paranaix

+0

@Paranaixこれが起こったときは、常に中括弧のレベルを追加してみてください。私。 'm = {{{1、2、3}}、{4,5,6}、{7,8,9}}}。新しいレベルの中括弧は 'Matrix <3, 3>'であり、 'm = Matrix <3, 3> {{1,2,3}、{4,5,6}、{7,8,9}}'と同等です。 –

+0

残念ながら、これは動作しません。コンストラクタを "明示的に"宣言して、変換コンストラクタが不可能であることを明確にする必要があります。 – Paranaix

1
no known conversion for argument 1 from ‘<brace-enclosed initializer list>’ to ‘double (&)[3][3]’ 

は、変数宣言で存在することができます。コードのいくつかの行は、一度コンパイルすると、最初の例は2番目のフットプリントより多くのフットプリントを持つべきではありません。