In C++, I’m trying to create a specialized point class as a union, like so:
union point
{
struct { float x, y, z; };
float val[3];
float operator[](unsigned i) { return val[i]; }
};
So that I can access the point as an array or as multiple points, for readability.
However, let’s say that I want to generalise this a bit:
template<unsigned n>
union point
{
struct { float ???; };
float val[n];
float operator[](unsigned i) { return val[i]; }
};
What can I put for ???? I could have x, x, y, x, y, z, or x, y, z, w depending on what n is. Solution? Forward declarations!
template<unsigned n>
union point
{
struct coords;
float val[n];
float operator[](unsigned i) { return val[i]; }
};
template<>
struct point::coords<3>
{
float x, y, z;
};
// ...
But this doesn’t appear to work. Under the GCC 4.6, it compiles, however, whenever that I try to use the members, like so:
point<3> val;
val.x;
I get the error:
error: ‘union point<3>’ has no member named ‘x’
Even if I change val.x to val.coords::x, I still get the error:
error: ‘union point<3>::coords’ is not a base of ‘union point<3>’
Adding using coords; in the union definition didn’t help, either.
Is there any way to accomplish this under the GCC 4.6? Is there a different method of doing this? Is it even possible?
I would suggest using variadic macro to define your
union<N>templates.Having done this, you can simply declare/define your various combinations for coordinates (before
#undefin this case):that is equivalent to,
It can be used in the same way you asked:
Also, you can put a cross check using some template trickery (
static_assert) to check the number arguments(e.g.1,2,3,...) match the total argument passed (e.g.x,y,z,...).