dimanche 3 janvier 2016

Unions in C++11: constructor seems to be deleted

I am trying to understand how unions were extended by C++11. One thing that changed is the ability to use now non-static data members with non-trivial special member functions. From cppreference.com

If a union contains a non-static data member with a non-trivial special member function (default constructor, copy/move constructor, copy/move assignment, or destructor), that function is deleted by default in the union and needs to be defined explicitly by the programmer. At most one data member can have a default member initializer.

I am trying the following code:

struct X
{
    ~X() {};
};

union U
{
    X x;
    ~U() {};
};

int main()
{
    U s1{};  // works, probably aggregate initialization
    U s2;    // DOES NOT compile, why?
}

Live on Coliru

Here X (which is used as a data member of the union) has a user provided destructor, hence the destructor of the union is by default deleted. Therefore I provide one explicitly. However, the code fails to compile, with the error

note: 'U::U()' is implicitly deleted because the default definition would be ill-formed:

The code compiles if I remove the last line U s2;.

Question What is going on here? Why U s1{}; compiles, but U s2; does not? Is the default ctor of the union marked as deleted (if so, why?!), and in the first case we have just aggregate initialization? Note that if I provide U(){}; // not U() = default; the code compiles (but not if I only provide a ctor of X).

Compiler(s): g++5.3, clang++3.7, -std=c++11 used.

Aucun commentaire:

Enregistrer un commentaire