On Sunday, 3 October 2021 at 22:22:48 UTC, rjkilpatrick wrote:
```d
void main() {
// When we use `SuperClass[] list;` here, we find 'a' is
hidden by the base class
Variant[] list;
// Attempting to append derived class instances to list
list ~= new DerivedClass(1.0f);
list ~= new OtherDerivedClass;
list[0].a;
list[0].to!(get!(list[0].type)).a.writeln;
}
```
This works:
```d
void main() {
Variant[] list;
list ~= new DerivedClass(1.0f).Variant;
list ~= new OtherDerivedClass().Variant;
writeln(list[0].get!DerivedClass.a);
}
```
Parameters passed in !() need to be statically known, at
compile-time, so `get!(list[0].type)` doesn't make sense with a
runtime list.
If everything in the list is going to be a child of some class,
then you don't need std.variant at all, you can just use OOP:
```d
import std.stdio : writeln;
class SuperClass {
this() {
}
}
class DerivedClass : SuperClass {
public:
this(float a) {
this.a = a;
}
float a;
}
class OtherDerivedClass : SuperClass {}
class YetAnotherDerivedClass : SuperClass {}
void main() {
SuperClass[] list;
list ~= cast(SuperClass) new DerivedClass(1.0f);
list ~= cast(SuperClass) new OtherDerivedClass;
list ~= cast(SuperClass) new YetAnotherDerivedClass;
writeln((cast(DerivedClass) list[0]).a);
foreach (obj; list) {
if (auto deriv = cast(DerivedClass) obj) {
writeln("I found a DerivedClass: ", deriv.a);
} else if (cast(OtherDerivedClass) obj) {
writeln("I found an OtherDerivedClass");
} else {
writeln("I found an unexpected child: ", obj);
}
}
}
```
output:
```
1
I found a DerivedClass: 1
I found an OtherDerivedClass
I found an unexpected child: variant.YetAnotherDerivedClass
```
Object casts like that are `null` when the cast is invalid.
If you don't necessarily have a superclass, but still do have a
definite number of possible member types, you can use std.sumtype:
```d
import std.stdio : writeln;
import std.sumtype;
struct A { float a; }
struct B { }
struct C { }
alias Alpha = SumType!(A, B, C);
void main() {
Alpha[] list;
list ~= A(1.0f).Alpha;
list ~= B().Alpha;
list ~= C().Alpha;
list[0].tryMatch!((A a) => writeln(a.a));
foreach (obj; list) {
obj.match!(
(A a) => writeln("I found A(", a.a, ")"),
(B _) => writeln("I found B"),
(C _) => writeln("I found C"),
);
}
}
```
output:
```
1
I found A(1)
I found B
I found C
```