我有一个简单的矩阵类,如下所示:
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;
}
上面的代码编译没有错误。我做错了什么?
我知道我可以简单地在函数体中放置一个static_assert(m == 4 && n == 4)
,但我正在寻找一个更清晰的解决方案,并希望在此过程中了解一些有关模板的内容。 < / p>
答案 0 :(得分: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
}
这是live example。请注意,调用translate()
时是如何触发编译错误的,而不仅仅是matrix<4,3>
的实例化。
答案 1 :(得分:0)
你可以使用&amp;&amp;和=_在enable_if的参数中。此外,您忘记了:: type,它是仅在条件为真时才存在的成员(启用也是如此)。这还需要添加一个typename。以下是有效的代码:
#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;
}