gpt4 book ai didi

C++ 默认构造函数与具有非平凡默认构造函数的变体成员 union

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:50:17 24 4
gpt4 key购买 nike

我最近阅读了 union 体默认构造函数的描述: Default Constructor

有如下规律:

Blockquote Deleted implicitly-declared default constructor: [...] T is a union with at least one variant member with non-trivial default constructor, and no variant member of T has a default member initializer.[...]

然后我决定做一个练习来验证规则。

struct Member {
public:
// Member() : mX(0) {}
virtual int GetX() {
return mX;
}
int mX;
};

union DefaultConstructor {
int mA;
Member mMember;
int GetA();
};

使用 gcc v5.3.1(我知道它很旧)我收到预期的错误:

> ../src/DefaultConstrcutors.cpp: In function ‘void
> Test_DefaultConstructors()’: ../src/DefaultConstrcutors.cpp:26:22:
> error: use of deleted function
> ‘DefaultConstructor::DefaultConstructor()’ DefaultConstructor foo;
> ^ In file included from ../src/DefaultConstrcutors.cpp:19:0:
> ../src/DefaultConstructors.h:155:7: note:
> ‘DefaultConstructor::DefaultConstructor()’ is implicitly deleted
> because the default definition would be ill-formed: union
> DefaultConstructor {
> ^ ../src/DefaultConstructors.h:157:10: error: union member ‘DefaultConstructor::mMember’ with non-trivial ‘Member::Member()’
> Member mMember;
> ^

好的,所以根据规则,如果我为变体成员提供默认成员初始值设定项,那么它应该可以编译。所以我将 union 定义更改为:

union DefaultConstructor {
int mA = 0;
Member mMember;
int GetA();
};

现在应该可以编译了,但我收到了同样的错误。

下一步是为 mMember 而不是 mA 提供默认初始化程序(只有一个 union 变体成员可能具有默认初始化程序)。

union DefaultConstructor {
int mA;
Member mMember{};
int GetA();
};

现在可以编译了。

问题是:当 mA 具有默认初始化程序时,为什么在第二种情况下它没有编译?根据提到的规则,它应该是可能的。这里提供了更多类似的规则:Union declaration

If a union contains a non-static data member with a non-trivial default constructor, the default constructor of the union is deleted by default unless a variant member of the union has a default member initializer .

有人知道为什么它不起作用吗?

您好,彼得

最佳答案

cppreference 通常是一个很好的信息源,但这里的编译器是正确的。 C++11 的草案 n3337 在 9.5 union [class.union] 中包含一个非规范但明确的说明:

If any non-static data member of a union has a non-trivial default constructor (12.1), copy constructor (12.8), move constructor (12.8), copy assignment operator (12.8), move assignment operator (12.8), or destructor (12.4), the corresponding member function of the union must be user-provided or it will be implicitly deleted (8.4.3) for the union.

没有提到一个成员有一个默认的成员初始值设定项。

C++14 的 n4296 草案中仍然存在相同的说明,因此我认为它在实际的 C++ 标准中应该仍然相同。注释当然是非规范的,但它们的目的是使标准的解释更清楚,所以我认为 cppreference 的解释是错误的,因为它不尊重该注释,而 gcc 解释是正确的。

关于C++ 默认构造函数与具有非平凡默认构造函数的变体成员 union ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50405486/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com