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;
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:
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).
.. 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:
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 [..]
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
.