我有以下C ++代码(在VS2017中):
struct OptionA
{
std::string s1;
};
struct OptionB
{
std::string s2;
};
struct Inner
{
int b;
union {
OptionA optA;
OptionB optB;
}Options;
};
struct Outer
{
int a;
Inner b;
}
当我尝试声明此结构时:
int main()
{
Outer obj;
};
我收到编译错误:
错误C2280:'Outer :: Outer(void)':尝试引用已删除的文件 功能
这种声明结构的方法应该可以正常工作。我认为此错误与结构的构造函数有关。
我该如何解决这个问题?
答案 0 :(得分:4)
您的问题在于
union {
OptionA optA;
OptionB optB;
}Options;
在Inner
中。 OptionA
和OptionB
都是不可构造的,因此当您将它们合并时,它将删除该联合的构造函数。这意味着Options
不能默认构造,因此Inner
也不能,因为您没有提供默认构造函数。
您将需要为联合提供自己的构造函数和析构函数,以处理构造和破坏适当成员的情况。您可以看到如何制作带标签的联合以正确破坏联合here
答案 1 :(得分:3)
根据this:
如果联合包含具有非平凡的非静态数据成员 特殊成员函数(复制/移动构造函数,复制/移动分配, 或析构函数),则默认情况下会在联合中删除该函数, 需要由程序员明确定义。
因此,您需要在Inner
中为您的联合定义构造函数和析构函数。但是因为它是一个匿名联合,所以您必须先为其命名:
struct Inner
{
int b;
union A {
A();
~A();
OptionA optA;
OptionB optB;
} Options;
};