Not sure if there is a term for this, "choice" seems to work. I'm working in C++, and I have a bunch of unions I need to create where the union represents a choice of one of the members of the union. The current "choice" is tracked and is always available. I am currently coding these "unions" manually, but I'm wondering whether there is any neat trick for doing this sort of thing (semi-)automatically.
I ran into the union limitation of not having assignment operator overloads or non-trival constructors or copy constructors on my first bout of trying to implement this, but realized that because I'm actually tracking the current "choice", there is very defined behavior to take under almost every situation.
Here is what I'm doing right now, (for only two choices, could be up to 10 or 15) and it's quite a significant amount of code nearly all of which is just boilerplate. Also, if anyone has any comments on whether or not what I have below is even valid that would be awesome, still picking up some of the craziness of C++...
struct MyChoice
{
struct Choice1
{
int a;
char* b;
};
struct Choice2
{
bool c;
double d;
};
enum Choice
{
Choice_Choice1,
Choice_Choice2
} choice;
char _value[max(sizeof(Choice1),sizeof(Choice2))]; // could be private
Choice1& choice1()
{
if(choice == Choice_Choice2)
{
(*(Choice2*)_value)->~Choice2();
(*(Choice1*)_value) = Choice1();
choice = Choice_Choice1;
}
return *(Choice1*)_value;
}
Choice2& choice2()
{
if(choice == Choice_Choice1)
{
(*(Choice1*)_value)->~Choice1();
(*(Choice2*)_value) = Choice2();
choice = Choice_Choice2;
}
return *(Choice2*)_value;
}
MyChoice()
{
_choice = Choice_Choice1;
(*(Choice1)_value) = Choice1();
}
MyChoice(const MyChoice& other)
{
this->_choice = other.choice;
if(this->_choice == Choice_Choice1)
(*(Choice1*)_value) = other.choice1();
else
(*(Choice2*)_value) = other.choice2();
}
~MyChoice()
{
if(_choice == Choice_Choice1)
(*(Choice1)_value)->~Choice1();
else
(*(Choice2)_value)->~Choice2();
}
};
Thanks for your help SO
A union is a special data type available in C that allows to store different data types in the same memory location. You can define a union with many members, but only one member can contain a value at any given time. Unions provide an efficient way of using the same memory location for multiple-purpose.
Union is preferred over struct when only one of the member elements of the union is stored.
Union takes less memory space as compared to the structure. Only the largest size data member can be directly accessed while using a union. It is used when you want to use less (same) memory for different data members.
Try looking at boost::any and boost::variant. The first one enables you to insert any type in a boost::any variable, tracking its type. It's more a "check-at-runtime" type. The second one force you to define all the types to be inserted (ie boost::variant < Choice1, Choice2, ... > ), but enforce more type-checking at compile time.
Both are used to store object of different types, for example to have heterogeneous containes (std::vector can handle std::string or int for example).
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