根据模板类变量启用函数

Ove*_*erv 4 c++ templates

我有一个简单的矩阵类,如下所示:

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];
};
Run Code Online (Sandbox Code Playgroud)

我希望std::enable_if只有在实例化a时才能使该函数可用matrix<4,4>,但看起来这是错误的.

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

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

上面的代码编译没有错误.我究竟做错了什么?

我知道我可以简单地static_assert(m == 4 && n == 4)在函数体中添加一个,但我正在寻找一个更清晰的解决方案,并希望在这个过程中学习一些模板.

And*_*owl 6

对于初学者,您应该这样做:

typename std::enable_if<std::is_same<matrix, matrix<4,4>>::value, void>::type
Run Code Online (Sandbox Code Playgroud)

而不仅仅是:

std::enable_if<std::is_same<matrix, matrix<4,4>>::value, void>
Run Code Online (Sandbox Code Playgroud)

但是这仍然不起作用,因为在实例化类模板时将评估条件,因此即使您从未调用也会产生错误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
}
Run Code Online (Sandbox Code Playgroud)

这是一个实例.请注意,如何通过调用触发编译错误translate(),而不仅仅是实例化matrix<4,3>.