gpt4 book ai didi

c++ - 包含常量成员的 POD 结构

转载 作者:可可西里 更新时间:2023-11-01 15:24:52 25 4
gpt4 key购买 nike

使用这段代码:

struct A
{
int i;
const int b;
};

// The union is to verify that A is a type that can be used in a union.
union U
{
A a;
int b;
};

int main()
{
U a = {1, 1};
U b = {2, 1};
}

g++ 版本 4.8.3 报错:

a.cpp:9:4: error: member ‘A U::a’ with copy assignment operator not allowed in union
A a;
^
a.cpp:9:4: note: unrestricted unions only available with -std=c++11 or -std=gnu++11

但是 clang 3.5.0 编译这段代码没有错误。哪一个是正确的?这是编译器错误吗?

我尝试解决这个问题:

来自 C++03 标准第 9.5 节第 1 段:

In a union, at most one of the data members can be active at any time, that is, the value of at most one of the data members can be stored in a union at any time. [Note: one special guarantee is made in order to simplify the use of unions: If a POD-union contains several POD-structs that share a common initial sequence (9.2), and if an object of this POD-union type contains one of the POD-structs, it is permitted to inspect the common initial sequence of any of POD-struct members; see 9.2. ] The size of a union is sufficient to contain the largest of its data members. Each data member is allocated as if it were the sole member of a struct. A union can have member functions (including constructors and destructors), but not virtual (10.3) functions. A union shall not have base classes. A union shall not be used as a base class. An object of a class with a non-trivial constructor (12.1), a non-trivial copy constructor (12.8), a non-trivial destructor (12.4), or a non-trivial copy assignment operator (13.5.3, 12.8) cannot be a member of a union, nor can an array of such objects. If a union contains a static data member, or a member of reference type, the program is ill-formed.

来自 C++03 标准部分 12.8 第 10 和 11 段:

If the class definition does not explicitly declare a copy assignment operator, one is declared implicitly. The implicitly-declared copy assignment operator for a class X will have the form X& X::operator=(const X&) if each direct base class B of X has a copy assignment operator whose parameter is of type const B&, const volatile B& or B, and for all the nonstatic data members of X that are of a class type M (or array thereof), each such class type has a copy assignment operator whose parameter is of type const M&, const volatile M& or M.

Otherwise, the implicitly declared copy assignment operator will have the form X& X::operator=(X&) ...

A copy assignment operator for class X is trivial if it is implicitly declared and if class X has no virtual functions (10.3) and no virtual base classes (10.1), and each direct base class of X has a trivial copy assignment operator, and for all the nonstatic data members of X that are of class type (or array thereof), each such class type has a trivial copy assignment operator; otherwise the copy assignment operator is non-trivial.

我不确定哪个编译器是正确的,因为我不知道常量成员是否具有平凡的复制赋值运算符。

编辑:编译命令为:

clang++ a.cpp -o a
g++ a.cpp -o a

编辑2:为了表明 g++ 没有提示 A::b 是 const 但 A 没有构造函数,我还尝试了这个程序:

struct A
{
int i;
const int b;
};

int main()
{
A a = {1, 1};
}

此编译在 g++ 和 clang++ 上都没有错误:

g++ b.cpp -o b
clang++ b.cpp -o b

最佳答案

正如您正确指出的那样,复制赋值运算符是隐式声明 且微不足道的。默认构造函数也是如此,它也是微不足道且隐式声明的。

请注意,尽管这两个成员函数都没有隐式定义 - 只有在使用它们时才会发生,[class.ctor]/7:

An implicitly-declared default constructor for a class is implicitly defined when it is used to create an object of its class type (1.8).

.. 这显然不是这里的情况。
这是关键区别,也是 @dasblinkenlight 的引述与此事无关的原因:从未定义默认构造函数,因此关于缺少 mem-initializer-ids 的段落不适用。

那么 const 成员和赋值运算符是如何连接的呢?这里:

An implicitly-declared copy assignment operator is implicitly defined when an object of its class type is assigned a value of its class type or a value of a class type derived from its class type. A program is ill-formed if the class for which a copy assignment operator is implicitly defined has:

  • a nonstatic data member of const type, or [..]

因此,如果使用复制赋值运算符,程序将是病式的。但事实并非如此。所有特殊成员函数都是单独声明的,对非静态数据成员的 const 性的任何限制仅适用于隐式定义的特殊成员函数。

举个例子

struct A
{
int i;
const int b;
};

int main()
{
A a = {1, 1};
}

哪个compiles fine under GCC .您的程序也应该是良构的,因为 A 满足 union 成员的特殊成员函数的所有要求。

关于c++ - 包含常量成员的 POD 结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27665567/

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