The class template std::variant (C++17) represents a
type-safe union. An instance of std::variant at any given time either holds a value of one of its alternative
types, or in the case of error - no value.
If we define a variant v including lots of types, including booleans and lists, this would be somewhat similar to:
PHP: $v = 3.14; // see https://bit.ly/3cVuJvb
Python: v = 3.14;
Javascript: var v = 3.14;
As with unions, if a variant holds a value of some object type T, the object representation of T is allocated
directly within the object representation of the variant itself. Variant is not allowed to allocate additional
(dynamic) memory.
A variant is not permitted to hold references, arrays, or the type void. Empty variants are also ill-formed
(std::variant can be used instead).
A variant is permitted to hold the same type more than once, and to hold differently cv-qualified versions of the same type.
Consistent with the behavior of unions during aggregate initialization, a default-constructed variant holds a value
of its first alternative, unless that alternative is not default-constructible
(in which case the variant is not default-constructible either). The helper class std::monostate can be used
to make such variants default-constructible.
12345
unionmy_union{doublea;charb;intc;};
12345
// - It only works with fundamental data type// - It doesn't have convenience functionsmy_unionu={3.14};u={'A'};u={15};
12345
// A union is as large as the largest type in the unionstd::cout<<"sizeof(double): "<<sizeof(double)<<'\n';std::cout<<"sizeof(char): "<<sizeof(char)<<'\n';std::cout<<"sizeof(int): "<<sizeof(int)<<'\n';std::cout<<"sizeof(my_union): "<<sizeof(my_union)<<'\n';
// A variant is larger than the largest type in the variant// This happens because variants need a flag to indicate the current typestd::cout<<"sizeof(double): "<<sizeof(double)<<'\n';std::cout<<"sizeof(char): "<<sizeof(char)<<'\n';std::cout<<"sizeof(string): "<<sizeof(std::string)<<'\n';std::cout<<"sizeof(variant<double, char, std::string>): "<<sizeof(std::variant<double,char,std::string>)<<'\n';
// Applying function to whatever value type it holdsstd::visit([](autox){std::cout<<x<<'\n';},v);
1 2 3 4 5 6 7 8 91011
switch(v.index()){case0:std::cout<<"This is a double\n";break;case1:std::cout<<"This is a char\n";break;case2:std::cout<<"This is a string\n";break;}
1234567
if(std::holds_alternative<double>(v)){std::cout<<"This is a double\n";}elseif(std::holds_alternative<char>(v)){std::cout<<"This is a char\n";}elseif(std::holds_alternative<std::string>(v)){std::cout<<"This is a string\n";}