Variants can hold an arbitrary set of types.

I imagine that it is effectively just a type id and an object pointer!?

If so, then it really is just a special type of a class class.

Let me explain:

I have a class that will "hold/wrap" another class.

I could hold them using a variant but also I could require some new wrapper class that takes the object and include that wrapper class instead:

class A
{
   variant o;
}

vs

class A
{
   B oo;
}

class B
{
   ...
   Object ooo; // or variant
}


id matching on o is basically virtual functions. The matcher dispatching is single dispatch.


Of course, the class version gives compile time specificity since it provides a compile time interface that the variant does not represent.

It seems that variant and oop are essentially the same thing, more or less, as whatever can be done in one can effectively be done in the other, except, of course, that the class version has compile time type information associated with it, which sort of restricts variant to a subset of all types!?!

But variant can reduce the code complexity if one restricts it's inputs to a specific class of types:


struct VariantClass(T...)
{
    private Variant v;
    alias v this;
        static foreach(t; T)
                auto opAssign(t x)
                {
                        v = x;
                }


}



Then VariantClass will prevent any arbitrary type from being assigned to the variant, effectively allow inheritance to be used(in the sense that it will prevent any type from being used at compile time, like inheritance):

VariantClass!X v; // only T : X's are allowed.


Matching then is dispatch. We could further extend VariantClass to return specific classes for each type that dispatch to match and vice versa.

They might not be exactly the same though but it seems that they essentially both cover the same problem but from different perspectives.

Anyone have any thoughts? I'm mainly trying to decide if I should use a variant or go full oop. Variant seems more appropriate than using Object for a general purpose singleton container in that I can leverage it's design. If I use oop then it does require me to design an inheritance between the objects.

It would be cool if duck typing could be used though.

Essentially all I want to do is access a very small interface of the object that has a draw command and maybe a few other things. I want all the objects to posses these functions(be a duck) but other than that, I could care less.

Seems like I could extend the VariantClass to do introspection on the types and make sure they have the members I need but otherwise do not limit their types to inheritance but then it starts feeling like oop as I'll need to specify an interface.

Seems like partial interface matching is what is needed. One specifies an interface I and any object that partially matches it by design(contains same function signatures, regardless if it physically implements the interface).

Can D project interfaces like this?

interface I
{
   int foo(int);
}

I i = project!I(o);

project returns part of the interface o(can be object but must have a int foo(int)) that matches I or null otherwise.

Seems though this cannot be used at runtime though since function signatures are not transported in the binary? If they are, then maybe it would work and would reduce the overhead of oop as one could just project types to other types that overlap.










Reply via email to