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
```

Reply via email to