使用模板元编程的功能遗漏?

时间:2013-08-09 08:02:18

标签: c++ template-meta-programming

我刚开始学习模板元编程,我正试图了解其局限性。

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

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

2 个答案:

答案 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。