Generically call a function on Variant's payload?

Jonathan M Davis newsgroup.d at jmdavisprog.com
Mon Aug 20 20:34:37 UTC 2018


On Monday, August 20, 2018 1:38:13 PM MDT Nick Sabalausky (Abscissa) via 
Digitalmars-d-learn wrote:
> There are a bunch of discriminated union types available for D, but the
> only one I'm aware of that *doesn't* require a finite-sized list of
> types known ahead-of-time is Phobos's Variant. The only problem is
> calling a function on a type not already known ahead-of-time. Maybe
> that's unsolvable? If so, then I'll fallback to the std.digest approach.
> But I'd prefer to avoid that, if possible.

It can be done if you know the list of types ahead of time, but you
basically have to check which type it is at runtime and then pick which code
to run based on that type, which means that you're essentially duplicating a
portion of the code for every type - though depending, it would be possible
to do something like templatize the code so that you don't have to
explicitly dulpicate it. But in the end, aside from using classes, if you're
using a variant type, I think that you're stuck doing something like

// exact API made up here rather than bothering to take the type to look up
// Variant's API.
void popFront()
{
    foreach(T; TypesThatVariantHolds)
    {
        if(_variant.contains!T)
        {
            auto v = _variant.get!T;
            v.popFront();
            return;
        }
    }
}

On the other hand, if you don't know the exact list of types ahead of time
or require that the code calling this code tell you which type to use, then
you're pretty much stuck using something like classes or delegates. You
can't just call functions on completely unknown types, because the compiler
wouldn't know what code to generate or what to link against.

- Jonathan M Davis





More information about the Digitalmars-d-learn mailing list