用于 3D 数学的模板 Vector 类的代码重用问题

发布于 2024-10-25 13:11:23 字数 389 浏览 1 评论 0原文

我有一个用于 3D 矢量数学的模板 Vector 类。我希望拥有此类不同类型和大小的变体(例如 Vec2i、Vec2f、Vec3i、Vec3f),并且能够从另一个构造一个,如下所示:

Vec2i v(1, 2);
Vec3f u = Vec3f(v, 0);

目前,我在 Vector 中有许多构造函数用于完成这。但是,允许以与上述相同的方式构造 Vec4 似乎是不正确的:

Vec4f t = Vec3f(v, 0)

我希望为 Vec2*、Vec3*、Vec4* 变体提供单独的类,但这意味着代码重复。我该怎么做?从 Vector 基类继承?根据原始 Vector 类实现每个变体(即 Vector 类是每个变体的私有成员)?

I have a template Vector class for 3D vector math. I'd like to have variants of this class of different type and size (e.g. Vec2i, Vec2f, Vec3i, Vec3f) and be able to construct one from the other, like so:

Vec2i v(1, 2);
Vec3f u = Vec3f(v, 0);

Currently, I have a number of constructors in Vector for accomplishing this. However, it seems incorrect to allow a Vec4 to be constructed in the same way as above:

Vec4f t = Vec3f(v, 0)

I'd like to have separate classes for Vec2*, Vec3*, Vec4* variants, but that means code duplication. How should I do this? Inheritance from a base Vector class? Implement each variant in terms of the original Vector class (i.e. the Vector class is a private member of each variant)?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

和影子一齐双人舞 2024-11-01 13:11:23

在我看来,Vec2 和 Vec3 是完全不同的,如果它们相关,您期望重用什么样的代码?

对于不同的内置类型,只需使用模板类和模板构造函数即可:

template<typename T1> 
struct Vec2 {
    Vec2(T1 const & X, T1 const & Y) : x(X), y(Y) {}
    template <typename T2> 
    Vec2(Vec2<T2> const & V) {
        x = static_cast<T1>(V.x);
        y = static_cast<T1>(V.y);
    }

    T1 x, y;
};


template<typename T1> 
struct Vec3 {
    Vec3(T1 const & X, T1 const & Y, T1 const & Z) : x(X), y(Y), z(Z) {}
    template <typename T2> 
    Vec3(Vec3<T2> const & V) {
        x = static_cast<T1>(V.x); 
        y = static_cast<T1>(V.y);
        z = static_cast<T1>(V.z);
    }
    template <typename T2, typename T3> 
    Vec3(Vec2<T2> const & V, T3 const & Z) {
        x = static_cast<T1>(V.x);
        y = static_cast<T1>(V.y);
        z = static_cast<T1>(Z);
    }

    T1 x, y, z;
};

如果要使 Vec2 和 Vec3 相关,请让 Vec3 模板继承 Vec2 模板,然后隐藏需要为 Vec3 重写的函数。

A Vec2 and a Vec3 are quite different IMO, what code reuse would you expect if they were related?

For the different built-in types, simply use template classes and template constructors:

template<typename T1> 
struct Vec2 {
    Vec2(T1 const & X, T1 const & Y) : x(X), y(Y) {}
    template <typename T2> 
    Vec2(Vec2<T2> const & V) {
        x = static_cast<T1>(V.x);
        y = static_cast<T1>(V.y);
    }

    T1 x, y;
};


template<typename T1> 
struct Vec3 {
    Vec3(T1 const & X, T1 const & Y, T1 const & Z) : x(X), y(Y), z(Z) {}
    template <typename T2> 
    Vec3(Vec3<T2> const & V) {
        x = static_cast<T1>(V.x); 
        y = static_cast<T1>(V.y);
        z = static_cast<T1>(V.z);
    }
    template <typename T2, typename T3> 
    Vec3(Vec2<T2> const & V, T3 const & Z) {
        x = static_cast<T1>(V.x);
        y = static_cast<T1>(V.y);
        z = static_cast<T1>(Z);
    }

    T1 x, y, z;
};

If you want to make Vec2 and Vec3 related, have the Vec3 template inherit the Vec2 template, then hide the functions you need to rewrite for Vec3.

定格我的天空 2024-11-01 13:11:23

使用模板。这是完全未经测试的。

template <int N>
struct Vec
{
    Vec(const Vec<N - 1>& smaller_vec, double v) { std::copy(&smaller_vec.values[0], &smaller_vec.values[0] + N-1, &values[0]); values[N-1] = v; }

    double values[N];
};

template <>
struct Vec<1>
{
    Vec(double v) { values[0] = v; }

    double values[1];
};

Vec<3> v3(Vec<2>(Vec<1>(5), 6), 7);

Use templates. This is totally untested.

template <int N>
struct Vec
{
    Vec(const Vec<N - 1>& smaller_vec, double v) { std::copy(&smaller_vec.values[0], &smaller_vec.values[0] + N-1, &values[0]); values[N-1] = v; }

    double values[N];
};

template <>
struct Vec<1>
{
    Vec(double v) { values[0] = v; }

    double values[1];
};

Vec<3> v3(Vec<2>(Vec<1>(5), 6), 7);
梦忆晨望 2024-11-01 13:11:23

像这样的东西?

template <int size, typename T>
struct Vec
{
    Vec<size, T>() {}
    Vec<size, T>(Vec<size-1, T>, T val) {} // here's the fun
};

typedef Vec<2, float> Vec2f;
typedef Vec<3, float> Vec3f;
typedef Vec<4, float> Vec4f;
// ...

int main()
{
    Vec2f john;
    Vec3f casey(john, 0);
    Vec4f chuck(casey, 0);

    return 0;
}

Something like this ?

template <int size, typename T>
struct Vec
{
    Vec<size, T>() {}
    Vec<size, T>(Vec<size-1, T>, T val) {} // here's the fun
};

typedef Vec<2, float> Vec2f;
typedef Vec<3, float> Vec3f;
typedef Vec<4, float> Vec4f;
// ...

int main()
{
    Vec2f john;
    Vec3f casey(john, 0);
    Vec4f chuck(casey, 0);

    return 0;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文