"追溯联盟" - 可以做到吗?

Xav*_*olt 3 c++ templates unions

我有两个类:一个模板类,一个继承它的常规类:

template <int N> class Vector
{
    float data[N];
    //etc. (math, mostly)
};

class Vector3 : public Vector<3>
{
    //Vector3-specific stuff, like the cross product
};
Run Code Online (Sandbox Code Playgroud)

现在,我想在子类中使用x/y/z成员变量(完整成员,而不仅仅是getter - 我希望能够设置它们).但是,为了确保所有的(继承)数学的作品出来,x就必须引用相同的内存data[0],ydata[1]等从本质上讲,我希望有一个工会,但我不能在基类中声明了一个,因为我不t知道该点向量中的浮点数.

那么 - 这可以吗?是否有某种预处理器/ typedef /模板魔法可以实现我正在寻找的东西?

PS:我正在使用带有-std = c ++ 0x的g ++ 4.6.0,如果有帮助的话.

编辑:虽然引用会给出我正在寻找的语法,但理想的解决方案不会使类更大(并且引用做了很多!A Vector<3>是12个字节.Vector3带参考的A 是40!).

Nim*_*Nim 8

怎么样:

class Vector3 : public Vector<3>
{
public:
  // initialize the references...
  Vector3() : x(data[0]), y(data[1]), z(data[2]){}
private:
  float& x;
  float& y;
  float& z;
};
Run Code Online (Sandbox Code Playgroud)

当然,如果你想让它们占据同一个空间,那就是另一个故事......

使用一点模板魔法,您可以执行以下操作...

#include <iostream>

template <int N, typename UnionType = void*> struct Vector
{
    union
    {
      float data[N];
      UnionType field;
    };

    void set(int i, float f)
    {
      data[i] = f;
    }

    // in here, now work with data
    void print()
    {
      for(int i = 0; i < N; ++i)
        std::cout << i << ":" << data[i] << std::endl;
    }
};

// Define a structure of three floats
struct Float3
{
  float x;
  float y;
  float z;
};

struct Vector3 : public Vector<3, Float3>
{
};

int main(void)
{
  Vector<2> v1;
  v1.set(0, 0.1);
  v1.set(1, 0.2);
  v1.print();

  Vector3 v2;
  v2.field.x = 0.2;
  v2.field.y = 0.3;
  v2.field.z = 0.4;
  v2.print();

}
Run Code Online (Sandbox Code Playgroud)

编辑:阅读完评论后,我意识到我之前发布的内容确实没有什么不同,所以稍微调整一下上一次迭代就可以直接访问该字段(这就是我猜你会想到的) - 我想这个之间的区别而Rob的解决方案是你不需要所有专业知识来反复实现所有逻辑......


Rob*_*obᵩ 7

模板专业化怎么样?

template <int N> class Vector
{
  public:
  float data[N];
};

template <>
class Vector<1>
{
  public:
  union {
    float data[1];
    struct {
      float x;
    };
  };
};

template <>
class Vector<2>
{
  public:
  union {
    float data[2];
    struct {
      float x, y;
    };
  };
};


template <>
class Vector<3>
{
  public:
  union {
    float data[3];
    struct {
      float x, y, z;
    };
  };
};

class Vector3 : public Vector<3>
{
};

int main() {
  Vector3 v3;
  v3.x;
  v3.data[1];
};
Run Code Online (Sandbox Code Playgroud)


编辑好的,这是一种不同的方法,但它引入了额外的标识符.

template <int N> class Data
{
  public:
  float data[N];
};

template <> class Data<3>
{
  public:
  union {
    float data[3];
    struct {
      float x, y, z;
    };
  };
};

template <int N> class Vector
{
  public:
  Data<N> data;
  float sum() { }
  float average() {}
  float mean() {}
};

class Vector3 : public Vector<3>
{
};

int main() {
  Vector3 v3;
  v3.data.x = 0; // Note the extra "data".
  v3.data.y = v3.data.data[0];
};
Run Code Online (Sandbox Code Playgroud)