4

次のような単純なマトリックス クラスがあります。

template <int m, int n>
class matrix {
public:
    std::enable_if<std::is_same<matrix, matrix<4,4>>::value, void>
    translate(float x, float y, float z) {
        // Do stuff
    }

private:
    float mat[m * n];
};

std::enable_ifをインスタンス化した場合にのみ関数を使用できるようにすることを期待してmatrix<4,4>いましたが、これは間違っているようです。

int main() {
    matrix<4, 3> mat3;
    mat3.translate(1.0f, 1.0f, 1.0f);

    return 0;
}

上記のコードはエラーなしでコンパイルされます。私は何を間違っていますか?

関数本体に単純に astatic_assert(m == 4 && n == 4)を入れることができることはわかっていますが、よりクリーンなソリューションを探しており、その過程でテンプレートについて何かを学びたいと思っています。

4

2 に答える 2

6

まず、次のことを行う必要があります。

typename std::enable_if<std::is_same<matrix, matrix<4,4>>::value, void>::type

代わりに:

std::enable_if<std::is_same<matrix, matrix<4,4>>::value, void>

ただし、クラス テンプレートがインスタンス化されるときに条件が評価され、 を呼び出さなくてもエラーが発生するため、これでも機能しませんtranslate()

C++11 を使用できる場合は、次のことができます。

template<typename T = matrix>
typename std::enable_if<
    std::is_same<T, matrix<4,4>>::value>
    ::type
translate(float x, float y, float z) {
    // Do stuff
}

これが実際のです。translate()の単なるインスタンス化ではなく、の呼び出しによってコンパイル エラーがどのようにトリガーされるかに注意してくださいmatrix<4,3>

于 2013-06-21T20:53:18.930 に答える
0

enable_if の引数に && と == を使用するだけです。また、条件が true の場合にのみ存在するメンバーである ::type を忘れていました (有効化も同様です)。これには、型名も追加する必要があります。動作するコードは次のとおりです。

#include <type_traits>

template <int m, int n>
class matrix {
public:
    typename std::enable_if<m == 4 && n == 4, void>::type
    translate(float x, float y, float z) {
       // Do stuff
    }

private:
    float mat[m * n];
};

int main() {
    // Compile fine
    matrix<4, 4> mat4;
    mat4.translate(1.0f, 1.0f, 1.0f);

    // Compile error
    matrix<4, 3> mat3;
    mat3.translate(1.0f, 1.0f, 1.0f);

    return 0;
}
于 2013-06-21T20:52:32.483 に答える