我刚开始学习模板元编程,我正试图了解其局限性。
以下列triangle_t
课程为例:
struct triangle_t
{
triangle_t() { }
triangle_t(vec3_t v0, vec3_t v1, vec3_t v2) : v0(v0), v1(v1), v2(v2) { }
vec3_t v0;
vec3_t v1;
vec3_t v2;
vec3_t normal();
};
现在,三角形可以是2维和3维,所以也许我想让它成为模板化的类,如下所示:
namespace detail
{
template<typename T>
struct triangle_t
{
triangle_t() { }
triangle_t(T v0, T v1, T v2) : v0(v0), v1(v1), v2(v2) { }
T v0;
T v1;
T v2;
T normal();
};
};
typedef detail::triangle_t<vec2_t> triangle2_t;
typedef detail::triangle_t<vec3_t> triangle3_t;
到目前为止,除了一个问题外,一切都很好。二维三角形没有法线。所以我想做的是,通过模板元编程,省略normal()
结构的triangle2_t
函数。
我尝试执行以下实现:
template<typename U = T>
typename std::enable_if<std::is_same<U, vec3_t>::value, U>::type normal() const
{
return glm::cross((v1 - v0), (v2 - v0));
}
我收到了这个错误:
错误C4519:只允许在类上使用默认模板参数 模板
我正在尝试做什么?如果没有,是否有任何类似的方法可以提供相同的结果?
答案 0 :(得分:4)
使normal
非会员功能。
template<typename T>
typename std::enable_if<std::is_same<T, vec3_t>::value, T>::type normal(triangle_t<T> const& t)
{
return glm::cross((t.v1 - t.v0), (t.v2 - t.v0));
}
或更好(不需要tmp)
vec3_t normal(triangle_t<vec3_t> const& t)
{
return glm::cross((t.v1 - t.v0), (t.v2 - t.v0));
}
答案 1 :(得分:0)
我可能会这样做:
namespace detail
{
template<typename T>
struct triangle_t
{
triangle_t() { }
triangle_t(T v0, T v1, T v2) : v0(v0), v1(v1), v2(v2) { }
T v0;
T v1;
T v2;
};
template<typename T>
struct triangle_with_normal_t : triangle_t<T>
{
// constructors here
T normal();
};
};
typedef detail::triangle_t<vec2_t> triangle2_t;
typedef detail::triangle_with_normal_t<vec3_t> triangle3_t;
但这不一定是TMP。