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.