C++并集中的命名结构
Named Structures in C++ Unions
在C++中,我试图创建一个专门的点类作为并集,如下所示:
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]; }
};
我可以为???
输入什么?根据n
是什么,我可以有x
、x, y
、x, y, z
或x, y, z, w
。解决方案?转发声明!
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>’
在联合定义中添加using coords;
也没有帮助。
根据GCC 4.6,是否有任何方法可以实现这一点?有不同的方法吗?这可能吗?
我建议使用可变宏来定义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,...
)是否匹配。
工会内部的这一行:
struct coords;
forward声明了类型coords
,但在模板化的并集中没有struct coords
字段。
此外,只有匿名结构的成员才能作为联合的顶级字段访问。例如:
union foo {
struct { // anonymous struct
short i;
short j;
};
int k;
};
foo f;
// it's possible to access the fields of the anonymous struct as if they were
// direct members of the union
f.i = 4;
f.j = 8;
std::cout << f.k;
如果你只专门化内部的struct
类型,我不确定你是否能够做到这一点。
然而,这是有效的:
template<unsigned n>
union point;
template<>
union point<2> {
struct { float x, y; };
float val[2];
};
template<>
union point<3> {
struct { float x, y, z; };
float val[3];
};
但也有许多不利因素;主要的一点是,您必须为CCD_ 19的每个版本重新定义CCD_。
我知道如何使用模板,但我不是模板之神,所以存在一个聪明的技巧并不是毫无疑问的。
相关文章:
- 如何循环打印顶点结构
- 通过方法访问结构
- 使用不带参数的函数访问结构元素
- 预处理器:插入结构名称中的前一个行号
- 为什么在没有显式默认构造函数的情况下,将另一个结构封装在联合中作为成员的结构不能编译
- 孤立代码块在结构中引发异常
- 有什么方法可以遍历结构吗
- 如何在 C# 中映射双 C 结构指针?
- 如何在C++中使用结构生成映射
- 无法将结构注册为增强几何体3D点
- 多成员Constexpr结构初始化
- C++将文本文件中的数据读取到结构数组中
- 如何重构类层次结构以避免菱形问题
- 如何在C++中序列化结构数据
- std::vector的包装器,使数组的结构看起来像结构的数组
- 访问内联程序集中的 C 结构成员
- 使用结构参数从程序集中调用C++函数
- 在并集中命名数组元素或结构和数组
- C++并集中的命名结构
- 获取存储在C++集中的结构中的值