1. ホーム
  2. c++

[解決済み] 警告を表示します。ISO C++は可変長配列を禁じています

2022-01-28 01:23:21

質問

浮動小数点配列へのポインタを取る関数があります。他の条件から、そのポインタは実際には 2x2 または 3x3 の行列を指していることが分かっています。(重要なのは、この判断を関数の引数としてではなく、関数本体で行いたいことです。

void calcMatrix( int face, float * matrixReturnAsArray )
{
    // Here, I would much rather work in natural matrix notation
    if( is2x2 )
    {
        // ### cast matrixReturnAsArray to somethingAsMatrix[2][2]
        somethingAsMatrix[0][1] = 2.002;
        // etc..
    }
    else if(is3x3)
    { //etc...
    }

}

float (somethingAsMatrix)[2] = (float ()[2]) matrixReturnAsArray; 

であれば、問題なく動作します。

ここで、ある条件に基づいて変化する変数として、添え字に値を書きたい場合。

これを実行すると、警告が表示されます。ISO C++は可変長配列を禁じています。このことから、どのように動的に何かを作成することができますか?

解決方法は?

C++の配列は、コンパイル時にサイズを定義する必要があります。

可変長の配列が必要な場合は std::vector の代わりに

あなたの場合、Matrix Size用のテンプレートを使って、Matrix Sizeごとに異なる実装をすることになりますね(あなたの意図を誤解していなければ)。

template<int SIZE> 
    struct Matrix {
    std::array<std::array<float, SIZE>,SIZE> m;
    std::array<float,SIZE>& operator[](int a) {
        if(a>=SIZE) {
            throw std::out_of_range("Out of range exception");
        }
        return m[a];
    }
};

template<int SIZE>
void calcMatrix(Matrix<SIZE>& matrixReturnAsArray );


template<>
void calcMatrix<2>(Matrix<2>& matrixReturnAsArray )
{
     // Code for 2x2 Matrix
    std::cout << "<2>" << std::endl;
    std::cout << matrixReturnAsArray[1][1] << std::endl;
}

template<>
void calcMatrix<3>(Matrix<3>& matrixReturnAsArray )
{
     // Code for 3x3 matrix
        std::cout << "<3>" << std::endl;
        std::cout << matrixReturnAsArray[2][2] << std::endl;
}

int main() {
   std::array<float,2> a={1,2};
   Matrix<2> m2;
   m2.m = {a,a};
   std::array<float,3> b={1,2,3};
   Matrix<3> m3;
   m3.m = {b,b,b};
   calcMatrix(m3); 
   calcMatrix(m2);
}

汎用テンプレートを定義していないので、サイズに2や3以外の値を使用すると、コンパイル時にエラーになります。

編集: Caleth の提案により、ポインタの代わりに std::array への参照を使用しました。

編集2: アクセスしやすいように演算子[]を追加し、安全のために例外を追加しました。