问题描述
使用此代码:
struct A
{
int i;
const int b;
};
//联合是验证A是可以在联合中使用的类型。
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'AU :: a'不允许在联合中使用复制赋值运算符
A a;
^
a.cpp:9:4:注意:无限制工会只能使用-std = c ++ 11或-std = gnu ++ 11
但clang 3.5.0会无错编译此代码。哪一个是对的?这是一个编译器错误吗?
我尝试解决这个问题:
C ++ 03标准第9.5节第1段:
+03 standard section 12.8 paragraph 10 and 11:
我不知道哪个编译器是正确的,因为我不知道常数成员有一个简单的复制赋值运算符。
编辑:
编译命令是:
clang ++ a.cpp -oa
g ++ a.cpp -oa
Edit2:
为了表明g ++没有抱怨A :: b是 const
但是A没有构造函数,我也尝试过这个程序:
struct A
{
int i;
const int b;
};
int main()
{
A a = {1,1};
}
在g ++和clang ++上编译时没有错误:
g ++ b.cpp -ob
clang ++ b.cpp -ob
正确地注意到,复制赋值操作符隐含地声明和微不足道。
默认构造函数也是如此,它也是微不足道的,并隐式声明。
请注意,这两个成员函数不是隐式定义的 - 只有在使用时才会发生,[class.ctor] / 7:
$ b当类用于创建类类型(1.8)的对象时,类是隐式地定义
$ b
..这显然不是这里的情况。
这是关键的区别,以及@ dasblinkenlight的引用与此事无关的原因:默认构造函数从未定义,因此段落
如何 const
成员和赋值运算符连接?这里:
如果使用副本分配操作符,将是不合格的。但它不是。所有的特殊成员函数都是单独声明的,对非静态数据成员的 const
的任何限制只适用于隐式定义的特殊成员函数。
例如,
struct A
{
int i;
const int b;
};
int main()
{
A a = {1,1};
}
其中。由于 A
满足所有关于成员职能的特殊成员职能的特殊要求,您的计划也应该具有良好的形式
With this code:
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++ version 4.8.3 complains about an error:
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
but clang 3.5.0 compiles this code without error. Which one is correct? Is this a compiler bug?
My attempt at solving this:
From the C++03 standard section 9.5 paragraph 1:
From the C++03 standard section 12.8 paragraphs 10 and 11:
I'm not sure which compiler is correct because I don't know if a constant member has a trivial copy assignment operator.
Edit:The compilation commands are:
clang++ a.cpp -o a
g++ a.cpp -o a
Edit2:To show that g++ isn't complaining about A::b being const
but A doesn't have a constructor, I also tried this program:
struct A
{
int i;
const int b;
};
int main()
{
A a = {1, 1};
}
This compiled without errors on both g++ and clang++:
g++ b.cpp -o b
clang++ b.cpp -o b
As correctly noted by you the copy assignment operator is implicitly declared and trivial.Same goes for the default constructor, which is also trivial and implicitly declared.
Note though that both of these member functions aren't implicitly defined - that only happens when they are used, [class.ctor]/7:
.. which is clearly not the case here.
That's the key difference, and the reason that @dasblinkenlight's quote is irrelevant for this matter: The default constructor is never defined, thus the paragraph on missing mem-initializer-ids doesn't apply.
How are const
members and the assignment operator connected then? Here:
Thus the program would be ill-formed if the copy assignment operator would be used. But it isn't. All the special member functions are solely declared, and any restrictions on the const
-ness of non-static data members only apply on implicitly defined special member functions.
As an example, take
struct A
{
int i;
const int b;
};
int main()
{
A a = {1, 1};
}
Which compiles fine under GCC. Your program should be well-formed, too, as all requirements on trivialty of special member functions of union members are met by A
.
这篇关于包含常量成员的POD结构的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!