您是否始终必须为包含具有用户定义的默认构造函数的成员的联合声明默认构造函数和析构函数?

Jen*_*nsB 0 c++ constructor default-constructor unions

这个类包含一个联合:

struct foo
{
    union
    {
        std::vector<int> vec;
        int i;
    };
};
Run Code Online (Sandbox Code Playgroud)

无法实例化。如果我尝试,编译器会抛出一个错误,指出'foo::foo(void)': attempting to reference a deleted function. 为了让它工作,我必须向联合添加一个空的构造函数和析构函数,如下所示:

struct foo
{
    union U
    {
        U() {}
        ~U() {}
        std::vector<int> vec;
        int i;
    } u_;
};
Run Code Online (Sandbox Code Playgroud)

然后就可以成功实例化了。情况总是如此吗?为什么?为每个包含具有用户定义的默认构造函数的成员的联合编写一个空的构造函数和析构函数似乎很愚蠢。

bol*_*lov 8

为......编写一个空的构造函数和析构函数似乎很愚蠢

不仅愚蠢,而且实际上是错误的。

为什么[编译器不生成一个而你需要]?

工会不知道其哪些成员是活跃的。因此,如果其至少一个成员具有非平凡的特殊方法,则联合体无法生成该特殊方法,因为它不知道在哪个成员上调用该特殊方法。

现在我们来谈谈你的情况。您确实需要编写一个特殊的方法,但将其清空则不会有任何效果。您需要编写一个特殊的方法来正确委托给活动成员。例如,在内部foo,您可以有一个数据成员(枚举或索引),它告诉您哪个联合成员处于活动状态。在您的联合特殊方法中,您检查该索引并对联合的活动成员调用特殊方法。

或者您可以忘记这一切,只使用标准库中的类型,它不仅为您设置了所有内容,而且是类型安全的:std::variant