template<typename T>
class MyClass
{
......
private:
union u_
{
struct m_
{
int i1;
int i2;
int i3;
} m;
char data[SIZE]; // convenience buffer for serialization/deserialization;
} u;
T container;
......
};
为了能够序列化/反序列化MyClass的对象,我使用union来组合我的数据字段并使用 data 缓冲区来批量处理。我想确保数据足够大,以便收集数据成员以防将来有人扩展它们,所以我添加了这个静态断言。
static_assert(sizeof(MyClass<int>::u_::data) >= sizeof(MyClass<int>::u_::m_));
这种方法存在两个问题。首先,编译器抱怨工会不公开。其次这适用于任何容器类型T,所以我不想具体,但是将int作为虚拟类型不起作用,但我不想仅仅为了静态断言而引入另一种类型,有没有办法在这里使用虚拟类型?
有更优雅的解决方案吗?
编辑:詹姆斯,感谢您提出可移植性问题。字节顺序和对齐是合法的问题,但在我的情况下,序列化/反序列化在本地发生,所以没关系。
答案 0 :(得分:1)
有更优雅的解决方案吗?
为什么不将结构重新解释为char数组?
struct m_
{
int i1;
int i2;
int i3;
};
// ...
m_ m;
char* data = static_cast<char*>(static_cast<void*>(&m));
任何对象都可以安全地重新解释为char数组。当然,您仍然需要担心对齐,填充,数据类型的大小以及潜在的字节序和其他表示问题,但可能您知道,因为您正在编写序列化实现。
答案 1 :(得分:1)
char data[SIZE];
而不是这样,你可以这样做:
char data[sizeof(m_)];
它始终满足此static_assert
中的条件:
static_assert(sizeof(MyClass<int>::u_::data) >= sizeof(MyClass<int>::u_::m_));
因为它总是满足,无论如何,你不甚至需要写static_assert
!
答案 2 :(得分:0)
要解决private
问题,您可以考虑将static_assert
放在类中的某个位置,例如构造函数或静态方法。