使用模板元编程的函数省略

Function omission using template meta-programming?

本文关键字:函数省 编程      更新时间:2023-10-16

我刚刚开始学习模板元编程,我正在努力理解它的局限性。

以以下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;

到目前为止一切都很好,除了一个问题。二维三角形没有法线。因此,我想通过模板元编程的方式,省略triangle2_t结构的normal()函数。

我尝试执行以下实现:

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

我想做的事情可能吗?如果没有,是否有类似的方法可以产生相同的结果?

使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));
}

我可能会这么做:

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。