如何防止无名称结构联合
How can I prevent a nameless structunion?
我正在构建一个矩阵数据有并集的类,但是,只有当我没有struct\union的名称时,我才能编译它。然而,有了更高级别的警告级别(视觉工作室上有四个),我会收到一个警告,说
warning C4201: nonstandard extension used : nameless struct/union
我调查了一下,似乎找不到防止这种情况发生的方法。无论如何,据我所知,可能会导致与其中一个或另一个的声明相关的不同编译器错误。如何在不禁用警告的情况下防止收到此警告并使其符合标准。
union
{
struct
{
F32 _11, _12, _13, _14;
F32 _21, _22, _23, _24;
F32 _31, _32, _33, _34;
F32 _41, _42, _43, _44;
};
F32 _m[16];
};
(是的,我知道有可用的矩阵库。请不要把这变成"使用xxx库"的讨论,我这样做是为了扩展我对C++的知识。)
命名它似乎是最好的。C++中允许匿名联合,只是不允许结构。
union
{
struct foo
{
F32 _11, _12, _13, _14;
F32 _21, _22, _23, _24;
F32 _31, _32, _33, _34;
F32 _41, _42, _43, _44;
} bar;
F32 _m[16];
};
您可以使用引用/宏来允许在没有bar
的情况下进行访问。
F32& _11 = bar._11;
F32& _12 = bar._12;
本质上与匿名结构相同。不过我并不真的推荐这个。如果可能,请使用bar._11
。
私有/公共(sorta):
struct mat
{
struct foo
{
friend class mat;
private:
F32 _11, _12, _13, _14;
F32 _21, _22, _23, _24;
F32 _31, _32, _33, _34;
F32 _41, _42, _43, _44;
};
union
{
foo bar;
F32 _m[16];
};
};
如果您只想在不更改实际代码的情况下禁用警告,那么您可以使用#pragma warning
指令,如下所示:
#pragma warning(disable : 4201)
如果你想再次启用它,请使用:
#pragma warning(default : 4201)
有关附加参考,请参阅MSDN文档。
union
{
struct // <- not named here
{
F32 _11, _12, _13, _14;
F32 _21, _22, _23, _24;
F32 _31, _32, _33, _34;
F32 _41, _42, _43, _44;
} AsStruct; // <- named here
F32 AsArray[16];
};
我修复了它,没有给结构类一个名称,只给实例名称。
我见过的解决这一问题的最常见方法是重载类型的数组运算符。它相当特定于您发布的示例,但类似的方法也可以用于其他情况,其中无名称结构似乎是唯一的选项。
struct Mat {
F32
_11, _12, _13, _14,
_21, _22, _23, _24,
_31, _32, _33, _34,
_41, _42, _43, _44;
f32& operator[](uint32 ndx) {
return *reinterpret_cast<F32*>(&((&_11)[ndx]));
}
const F32& operator[](uint32 ndx) const {
return *reinterpret_cast<const F32*>(&((&_11)[ndx]));
}
};
但是,在有矩阵的地方,通常有向量,这可以通过在向量类中定义类似于上面定义的数组运算符的数组运算符来对您有利。但是,不是在矩阵数组运算符中返回对F32的引用,而是返回对向量的引用。这里有一个例子:
struct vector4{
F32 x,y,z,w;
f32& operator[](uint32 ndx) {
return *reinterpret_cast<F32*>(&((&x)[ndx]));
}
const F32& operator[](uint32 ndx) const {
return *reinterpret_cast<const F32*>(&((&x)[ndx]));
}
};
struct matrix4 {
F32
_11, _12, _13, _14,
_21, _22, _23, _24,
_31, _32, _33, _34,
_41, _42, _43, _44;
vector4& operator[](uint32 ndx) { return *reinterpret_cast<vector4*>(&((&_11)[ndx * 4])); }
const vector4& operator[](uint32 ndx) const { return *reinterpret_cast<const vector4*>(&((&_11)[ndx * 4])); }
};
现在,代码可以更自然地编写,并且仍然高效,例如:
F32 m00 = mymat4[0][0];
或:
vector4 col0 = mymat4[0];
这种方法的最大缺点是矩阵现在必须是index[col][row]。这可以通过将运算符()添加到类中来解决。。。但那是另一回事。
您收到的警告不是关于内部结构,而是关于联合本身。试试这个:
union Mat // <-------
{
struct
{
F32 _11, _12, _13, _14;
F32 _21, _22, _23, _24;
F32 _31, _32, _33, _34;
F32 _41, _42, _43, _44;
};
F32 _m[16];
};
Mat mat;
mat._11 = 42;
F32 x = mat._22;
mat._m[ 3 ] = mat._33;
- 如何循环打印顶点结构
- 通过方法访问结构
- 防止主数据类型C++的隐式转换
- 使用不带参数的函数访问结构元素
- 预处理器:插入结构名称中的前一个行号
- 为什么在没有显式默认构造函数的情况下,将另一个结构封装在联合中作为成员的结构不能编译
- 孤立代码块在结构中引发异常
- 有什么方法可以遍历结构吗
- 如何在 C# 中映射双 C 结构指针?
- 如何在C++中使用结构生成映射
- 无法将结构注册为增强几何体3D点
- 如何防止引用返回的私有结构的突变
- 防止同级结构的相等比较
- C++ 编译器正在更改我的结构的对齐方式.我怎样才能防止这种情况
- 使用boost::序列化递归图结构时,如何防止堆栈溢出
- 如何防止无名称结构联合
- 如何防止类型被用作结构/类中的成员变量类型
- 具有虚拟性的多层层次结构可以防止强制转换函数指针
- 如何使用std::vector等动态数据结构并防止分页
- 防止嵌套的C++结构在父结构为 GC 时被删除