【问题标题】:Code reuse problem with a template Vector class for 3D math用于 3D 数学的模板 Vector 类的代码重用问题
【发布时间】:2011-03-24 18:07:01
【问题描述】:

我有一个用于 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 类是每个变体的私有成员)?

【问题讨论】:

    标签: c++ templates 3d


    【解决方案1】:

    Vec2 和 Vec3 是完全不同的 IMO,如果它们是相关的,你会期望什么代码重用?

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

    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 重写的函数。

    【讨论】:

    • 我最终做了类似的事情;我创建了 Vec2、Vec3、Vec4、Point2 和 Point3 实现的基本 Vector 类,以便重用 Vector 功能但仅公开其操作的子集(如 Point2 和 Point3 的情况)或添加功能(专门的构造函数)。
    【解决方案2】:

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

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

    【讨论】:

      【解决方案3】:

      这样的?

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-12-06
        • 2019-07-19
        • 1970-01-01
        • 1970-01-01
        • 2017-10-24
        • 2012-09-08
        • 2018-06-10
        • 1970-01-01
        相关资源
        最近更新 更多