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仅当我实例化 a 时才使该功能可用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 的参数中使用 && 和 ==。此外,您忘记了 ::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 回答