Variant is just a class

Josphe Brigmo JospheBrigmo at gmail.com
Thu Sep 6 10:18:43 UTC 2018


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.












More information about the Digitalmars-d mailing list