|
|
|
|
|
by tlhand
689 days ago
|
|
std::variant is not a true algebraic data type, since the individual element constructors do not construct the variant type automatically. Compare to OCaml, written in a verbose and unidiomatic way that is similar to C++: # type foo = Int of { n : int } | Float of { f : float };;
type foo = Int of { n : int; } | Float of { f : float; }
# Int { n = 10 };;
- : foo = Int {n = 10}
# let r = ref (Int { n = 10 });;
val r : foo ref = {contents = Int {n = 10}}
Notice that the constructor Int { n = 10 } automatically produces a foo type and assigning to a mutable ref works.The same in C++, using assignment to a pointer to avoid the lvalue ref error that is irrelevant to this discussion: #include <variant>
struct myint {
int n;
myint(int n) : n(n) {}
};
struct myfloat {
float f;
myfloat(float f) : f(f) {}
};
using foo = std::variant<myint, myfloat>;
int
main()
{
const foo& x = myint{10}; // works
foo *z = new myint{10}; // error: cannot convert ‘myint*’ to ‘foo*
}
As stated above, this obviously cannot work since C++ has no way of specifying a myint constructor that -- like in OCaml -- automatically produces the variant type foo.C++ would need true algebraic data types with compiler support (that would hopefully be as fast as switch statements). To be useful, they would need a nice syntax and not some hypothetical abomination like: using foo = std::variant<myint, myfloat> where
struct myint of foo { ... };
|
|