【发布时间】:2022-01-22 11:14:39
【问题描述】:
以下代码:
struct non_trivially {
non_trivially() {};
};
union U {
bool dummy{false};
non_trivially value;
};
int main() {
U tmp;
}
https://godbolt.org/z/1cMsqq9ee
在 clang (13.0.0) 上产生下一个编译器错误:
source>:11:7: error: call to implicitly-deleted default constructor of 'U'
U tmp;
^ <source>:7:19: note: default constructor of 'U' is implicitly deleted because variant field 'value' has a non-trivial default constructor
non_trivially value;
但使用 MSVC (19.30) 成功编译。
根据 cppreference,它应该是一个有效的代码:https://en.cppreference.com/w/cpp/language/union
如果联合包含具有非平凡默认构造函数的非静态数据成员,则默认删除联合的默认构造函数,除非联合的变体成员具有默认成员初始值设定项。
在我的示例中,U 中有一个带有默认成员初始值设定项的替代方法,因此不应删除默认构造函数,但确实如此。我错过了什么?
【问题讨论】:
-
问题不在于
dummy的默认成员初始化程序。问题在于value。例如,这可以正常工作(并且功能相同):ideone.com/GadqPM -
@scohe001 如果要相信 cppreference,我认为这不能回答问题。
-
当你解决这个问题并进行编译时,你仍然需要非常小心。很难让非平凡的
unions 正常工作。通常的建议是使用std::variant,但如果您想了解unions 的秘密方法,这并不是那么有用。 -
是的,
std::variant很神奇。 -
@user4581301 是的,当然,我在尝试实现变体 lol 时遇到了这种行为
标签: c++ language-lawyer