Variant is just a class
Neia Neutuladh
neia at ikeran.org
Thu Sep 6 20:25:18 UTC 2018
On Thursday, 6 September 2018 at 10:18:43 UTC, Josphe Brigmo
wrote:
>
> Variants can hold an arbitrary set of types.
>
> I imagine that it is effectively just a type id and an object
> pointer!?
It's a typeid and a static array large enough to hold any basic
builtin type: the now-deprecated creal, a dynamic array, or a
delegate.
If you make a Variant from an object, it stores that object
reference. The object reference is just a pointer, yes.
If you make a Variant from a 256-byte struct, it copies that
struct onto the heap and stores a pointer.
If you make a Variant from a 6-byte struct, then it stores that
struct and does no heap allocations.
> If so, then it really is just a special type of a class class.
It's similar to a java.lang.Object with explicit boxing, but
without the need to create a new wrapper class for each value
type.
> 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!?!
Object-oriented programming includes inheritance and member
function overloading. Variant doesn't; it's just about storage.
If you're working with classes, you'd be better off using a base
class or interface instead of Variant for fields that can only
hold objects of those types.
> But variant can reduce the code complexity if one restricts
> it's inputs to a specific class of types:
Yes, for which you can use std.variant.Algebraic. For instance,
Algebraic!(int, long, float) will accept ints, longs, and floats,
but nothing else.
> 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.
That's equivalent to `X v;` except with a wrapper around it.
> Matching then is dispatch. We could further extend VariantClass
> to return specific classes for each type that dispatch to match
> and vice versa.
I think you're saying that this sort of Algebraic could expose
any methods and fields common to all its types?
> Can D project interfaces like this?
>
> interface I
> {
> int foo(int);
> }
>
> I i = project!I(o);
You can write code to make that work. It would create a wrapper
class that implements the requested interface, and that wrapper
would just forward everything to the wrapped value.
It would be a lot easier just to have the type implement the
interface itself, if that's possible.
> 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.
You can use the witchcraft library on dub to perform runtime
introspection, but there would be a performance penalty.
More information about the Digitalmars-d
mailing list