Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
383 views
in Technique[技术] by (71.8m points)

c++ - Why do unions have a deleted default constructor if just one of its members doesn't have one?

N3797::9.5/2 [class.union] says:

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

I was trying to understand that note by example:

#include <iostream>
#include <limits>

struct A
{
    A(const A&){ std::cout << "~A()" << std::endl; } //A has no default constructor
};

union U
{
    A a;
};

U u; //error: call to implicitly-deleted default constructor of 'U'

int main()
{

}

DEMO

That behavior isn't quite clear to me. struct A doesn't have implicitly-declared default constructor, because 12.1/4: [class.ctor] says:

If there is no user-declared constructor for class X, a constructor having no parameters is implicitly declared as defaulted (8.4).

Which means struct A doesn't have a non-trivial default constructor (There is no default constructor at all, in particular non-trivial). That's union U doesn't have to have a deleted default constructor. What's wrong?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

The relevant wording is in C++11 [class.ctor]p5 (emphasis mine):

A default constructor for a class X is a constructor of class X that can be called without an argument. If there is no user-declared constructor for class X, a constructor having no parameters is implicitly declared as defaulted (8.4). [...] A defaulted default constructor for class X is defined as deleted if:

[...]

  • X is a union-like class that has a variant member with a non-trivial default constructor,

[...]

  • any direct or virtual base class, or non-static data member with no brace-or-equal-initializer, has class type M (or array thereof) and either M has no default constructor or overload resolution (13.3) as applied to M's default constructor results in an ambiguity or in a function that is deleted or inaccessible from the defaulted default constructor, or

[...]

Your class A has no default constructor, so a defaulted default constructor (whether implicit or explicit) for a class X (whether union or non-union) containing a non-static data member of type A without an initialiser leads to the default constructor for X being deleted. It has to: there's simply no way for the compiler to generate any other default constructor.

As for your follow-up question in the comments:

If instead of A not having a default constructor, it has a non-trivial default constructor, then there is a difference between using that in a union and in a non-union class, and that is also part of [class.ctor]p5: it is the first bullet point that I included, without emphasis, in my earlier quote.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...