C++ 我可以在不提供真实模板参数的情况下进行静态断言吗? 模板 类MyClass { ...... 私人: 联合大学_ { 结构m_ { int i1; int i2; int i3; }m; char data[SIZE];//用于序列化/反序列化的方便缓冲区; }u; T形容器; ...... };

C++ 我可以在不提供真实模板参数的情况下进行静态断言吗? 模板 类MyClass { ...... 私人: 联合大学_ { 结构m_ { int i1; int i2; int i3; }m; char data[SIZE];//用于序列化/反序列化的方便缓冲区; }u; T形容器; ...... };,c++,templates,C++,Templates,为了能够序列化/反序列化MyClass的对象,我使用一个union来组合数据字段,并使用数据缓冲区进行批量操作。我想确保数据足够大,足以收集数据成员,以防将来有人扩展它们,所以我添加了这个静态断言 template<typename T> class MyClass { ...... private: union u_ { struct m_ { int i1; int i2;

为了能够序列化/反序列化MyClass的对象,我使用一个union来组合数据字段,并使用数据缓冲区进行批量操作。我想确保数据足够大,足以收集数据成员,以防将来有人扩展它们,所以我添加了这个静态断言

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;
......
};
static_断言(sizeof(MyClass::u_uu::data)>=sizeof(MyClass::u_u::m_u));
这种方法有两个问题。首先,编译器抱怨工会不公开。其次,这对于任何容器类型T都是正确的,所以我不想说得太具体,但将int作为伪类型是行不通的,但我不想仅仅为了静态断言而引入另一种类型,这里有没有使用伪类型的方法

有更优雅的解决方案吗

编辑:詹姆斯,谢谢你提出可移植性问题。Endianness和alignment是合法的关注点,但在我的例子中,序列化/反序列化是在本地进行的,所以没关系

有更优雅的解决方案吗

为什么不将结构重新解释为字符数组呢

static_assert(sizeof(MyClass<int>::u_::data) >= sizeof(MyClass<int>::u_::m_));
struct m_
{
int i1;
int i2;
int i3;
};
// ...
m_m;
char*data=static_cast(static_cast&m));
任何对象都可以安全地重新解释为字符数组。当然,您仍然需要担心对齐、填充、数据类型的大小、潜在的endianness和其他表示问题,但您可能知道,因为您正在编写序列化实现

struct m_
{
    int i1;
    int i2;
    int i3;
};

// ...
m_ m;
char* data = static_cast<char*>(static_cast<void*>(&m));
您可以执行以下操作,而不是执行此操作:

char data[SIZE]; 
它将始终满足此
静态\u断言中的条件:

char data[sizeof(m_)]; 
static_断言(sizeof(MyClass::u_uu::data)>=sizeof(MyClass::u_u::m_u));

因为它总是满足的,不管怎样,你都不需要写
静态断言
私下的<代码>问题,你可以考虑把代码> STATICAYASPECT/<代码>放在类内的某个地方,比如一个构造函数或者一个静态方法。编译器可以在结构成员之间自由插入字节,而这些字节在运行时是完全未定义的;但是,原始代码(在问题中)有所有相同的问题,这至少是一个轻微的改进。@axel:是的,但是这个答案与原始问题的精神是一样的。另外,对我来说,两个结构具有相同类型(即布局)但填充不同的可能性似乎很小。@Axel:这不正是我在回答的最后一句中警告的吗?这并非在所有情况下都是一个“非常糟糕的主意”,而且有时是一种完全可以接受的移动数据的方式,特别是如果您控制通信通道的两侧。@James:如果您想编写可移植代码,则不是这样,不:pragmas基本上是特定于平台的。您所说的是真的,先生。谢谢
static_assert(sizeof(MyClass<int>::u_::data) >= sizeof(MyClass<int>::u_::m_));