0

私はについて何かを学ぼうとしていinitializer_list<>ます。私はc++03で学んだので、私にとっては新しいものです。

template <typename T>
union Matrix4
{
    struct
    {
        T m00, m01, m02, m03;
        T m10, m11, m12, m13;
        T m20, m21, m22, m23;
        T m30, m31, m32, m33;
    };

    T m[16];
    T mm[4][4];

    Matrix4(std::initializer_list<T> values)
    {
        if (values.size() != 16)
        {
            throw InvalidArgumentException;
        }

        std::copy(values.begin(), values.end(), m);
    }

    //error: Implicit instantiation of "Matrix4<float>" within its own definition.
    static Matrix4<float> Identityf = {
        1.f, 0, 0, 0,
        0, 1.f, 0, 0,
        0, 0, 1.f, 0,
        0, 0, 0, 1.f
    };
}

エラーの内容がわかります。私が得られないのは、なぜそれがそれを言っているのかということです。そのため、コンパイラはこれを処理できませんか?

私が達成したいのは、次のようなものです。

typedef Matrix4<float> Matrix4f;

Matrix4f mat = Matrix4f::Identity;
4

1 に答える 1

3

静的メンバーを初期化するIdentifyFには、コンストラクターを呼び出す必要があります。Matrix4コンストラクターは、特殊化を暗黙的にインスタンス化しますが、インスタンス化Matrix4<float>された時点では、クラステンプレートはまだ(完全に)定義されていません。

§14.7.1[temp.inst]

-7-クラステンプレートの特殊化の暗黙的なインスタンス化が必要であり、テンプレートが宣言されているが定義されていない場合、プログラムの形式が正しくありません。

クラス(またはクラステンプレート)は、そのクラス本体の閉じ中括弧で定義されます。

IdentityF定義をクラス本体からクラステンプレートが完成するポイントに移動することで、コードを機能させることができます。

template <typename T>
union Matrix4
{
    // ...

    static Matrix4<float> Identityf;
};

template<typename T>
Matrix<float> Matrix4<T>::Identityf = {
    1.f, 0, 0, 0,
    0, 1.f, 0, 0,
    0, 0, 1.f, 0,
    0, 0, 0, 1.f
};

この問題は初期化子リストとは関係ありません。その時点で使用されているすべてのコンストラクターに適用されます(コンストラクターがをとるだけではありませんinitializer_list) 。

于 2012-12-17T01:20:45.947 に答える