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;

これまでのところ、1 つの問題を除いて、すべてが順調に進んでいます。2 次元の三角形には法線がありません。したがって、私がやりたいことは、テンプレートのメタプログラミングによって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 に答える