I have a very basic struct that has an enum and a union.
typedef struct
{
enum v{a,b,c}v;
union w{
int a;
bool b;
std::string c;
}w;
}Data_Set2;
int main()
{
Data_Set2 val; // Shows errror that the default constructor cannot be referenced
return 0;
}
On using such a struct I get the Error Code C2280 that the default constructor cannot be referenced. When I declare the struct in a slightly different way as following
typedef struct
{
enum v{a,b,c}v;
union w{
int a;
bool b;
std::string c;
}; // changed here.
}Data_Set2;
The Error no longer exists. I fail to understand the reason behind this. Could anyone explain why this happens
From https://en.cppreference.com/w/cpp/language/union (or see standard):
If a union contains a non-static data member with a non-trivial special member function (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.
If a union contains a non-static data member with a non-trivial default constructor, the default constructor of the union is deleted by default unless a variant member of the union has a default member initializer .
At most one variant member can have a default member initializer.
In your case this means that you have to explicitly declare a constructor and destructor. Change your code to:
typedef struct
{
enum v{a,b,c} v;
union w{
int a;
bool b;
std::string c;
w() {} // Explicit constructor definition
~w() { }; // Explicit destructor definition
} w;
} Data_Set2;
This should work.
As already stated in my comment, you should however have a look at std::any
and std::variant
. The latter provides type-safe unions and would probably be the better choice in your case. Note that your compiler (apparently MSVC) needs to support C++17.
EDIT: As commented by eerorika, you will need to make sure that you only call it on the currently active member. The reference linked in the beginning shows an example for a string/vector union and how it introduces many pitfalls for undefined behavior. So unless you're just trying to understand what's happening behind the scenes or using POD types, I'd advise you work with std::variant
instead.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With