在 C++ 中,我试图创建一个专门的点类作为 union ,如下所示:
union point
{
struct { float x, y, z; };
float val[3];
float operator[](unsigned i) { return val[i]; }
};
这样我就可以以数组或多个点的形式访问点,以提高可读性。
但是,假设我想概括一下:
template<unsigned n>
union point
{
struct { float ???; };
float val[n];
float operator[](unsigned i) { return val[i]; }
};
我可以为 放什么???
?我可以有 x
、x, y
、x, y, z
或 x, y, z, w
取决于 n
是什么。解决方案?转发声明!
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;
};
// ...
但这似乎不起作用。在 GCC 4.6 下,它会编译,但是,每当我尝试使用成员时,如下所示:
point<3> val;
val.x;
我得到错误:
error: ‘union point<3>’ has no member named ‘x’
即使我将 val.x
更改为 val.coords::x
,我仍然会收到错误:
error: ‘union point<3>::coords’ is not a base of ‘union point<3>’
在 union 定义中添加 using coords;
也没有帮助。
在 GCC 4.6 下有什么办法可以做到这一点吗?有没有不同的方法来做到这一点?有可能吗?
最佳答案
我建议使用variadic 宏 来定义您的union<N>
模板。
template<unsigned int N>
union point; // declared and undefined
#define DECLARE_POINT(NUM, ...) \
template<> \
union point<NUM> \
{ \
struct { float __VA_ARGS__; }; \
float val[NUM]; \
}
#undef DECLARE_POINT
完成此操作后,您可以简单地声明/定义坐标的各种组合(在本例中为 #undef
之前):
DECLARE_POINT(1, x);
DECLARE_POINT(2, x, y);
DECLARE_POINT(3, x, y, z);
相当于,
template<> union point<1> { struct { float x; }; float val[1]; };
template<> union point<2> { struct { float x, y; }; float val[2]; };
template<> union point<3> { struct { float x, y, z; }; float val[3]; };
它可以按照您要求的方式使用:
point<3> p;
p.z = 0;
此外,您可以使用一些模板技巧 (static_assert
) 进行交叉检查,以检查参数数量(例如 1,2,3,...
)是否与传递的参数总数(例如 x,y,z,...
)匹配。
关于c++ - C++ union 中的命名结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6338645/