tags:

views:

79

answers:

2

I'm trying to make a generic vector class. While I can do something like this:

struct vector3 {
  union {
    struct {
      float x;
      float y;
      float z;
    };
    float v[3];
  };
};

I cannot do this:

template<int N, typename S, typename T = double>
class vec {
    union {
        T data[N];
        S;
    };
};

struct XY { REAL x, y; };
typedef vec<2, XY, REAL> Vector2;

because "S does not declare anything."

Is there any way to insert a generic template parameter as a member of a union? Essentially, I want to "inject" x and y fields into the vec class. Is there a better way of doing this?

+6  A: 

You need to name the member:

template<int N, typename S, typename T = double>
class vec {
    union {
        T data[N];
        S you_need_to_have_a_member_name_here;
    };
};

struct XY { REAL x, y; };
typedef vec<2, XY, REAL> Vector2;

But more importantly, what exactly are you trying to accomplish? If you want a heterogeneous container, you should do it via polymorphism. If you want a generic vector, use std::vector.

Also, you can't use templates to provide member names, only member types. What the above gets you will still be accessed as Vector2::you_need_to_have_a_member_name_here.x and Vector2::you_need_to_have_a_member_name_here.y.

edit1

OK, for what you're doing there's no really easy way. But there's a somewhat easy way (although it's pure evil).

#define Vec(D, X) struct Vector ## D { \
  X;  \
};

Vec(2, int x, y)
Vec(3, int x, y, z)
Vec(4, int w, x, y, z)
Vec(5, int v, w, x, y, z)

It's not pretty, safe, or sane, but it'll work. This is only if you really need specific member names. In general, there are safer ways if you can give up that requirement.

JoshD
It's not homework. What I'm trying to accomplish is define a vector to be used for linear algebra operations. I want to define the vector generically, i.e. so that I can have an N-dimensional vector. There are lots of overloaded operators and such that I've omitted from the code snippet above to keep it short. For convenience, it would be nice if x and y were members of vec<2>, { x, y, z} members of vec<3>, etc.
Ben Herila
Beautiful idea with edit1, although it **would** be pretty evil :-)
Ben Herila
+1  A: 

I think you need to implement tuple? That is what I understand from generic vector (I'm assuming this is vector space's vector, not std::vector). C++0x has this feature. Not sure which compiler implements it.

Donotalo
Ah, good point. If it is a vector (the linear algebra kind) he wants, tuple is the way to go. +1
JoshD
From OP's example, it looks like vector space's vector.
Donotalo