3

我刚刚开始学习模板元编程,并且试图了解它的局限性。

以下面的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:默认模板参数只允许在类模板上使用

我正在尝试做的事情可能吗?如果没有,是否有任何类似的方法可以提供相同的结果?

4

2 回答 2

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));
}
于 2013-08-09T10:00:36.557 回答
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。

于 2013-08-09T09:30:42.183 回答