std.variant.Algebraic, self referential types and delegate members
Panke via Digitalmars-d-learn
digitalmars-d-learn at puremagic.com
Sun Nov 8 03:44:02 PST 2015
On Sunday, 8 November 2015 at 11:28:05 UTC, Jonathan M Davis
wrote:
> On Sunday, November 08, 2015 10:31:11 Panke via
> Digitalmars-d-learn wrote:
>> import std.variant, std.stdio;
>>
>> ---
>> struct NodeTypeA(T) { T[] children; }
>> struct NodeTypeB(T) { Tree children; }
>> struct Leaf(T) { T delegate() dg; }
>>
>> alias Tree = Algebraic!(Leaf, NodeTypeA!This, NodeTypeB!This);
>>
>> void main()
>> {
>> Tree t;
>> }
>> ---
>>
>> yields
>>
>> tmp.d(6): Error: functions cannot return opaque type This by
>> value
>> tmp.d(8): Error: template instance tmp.Leaf!(This) error
>> instantiating
>>
>> This limitation seems arbitrary to me. What's the reason here?
>
> Okay. Several things here. For starters, NodeTypeA, NodeTypeB,
> and Leaf are not actually types. They're templates for types.
> If you want a type, you have to instantiate them. So, something
> like Algebraic!Leaf doesn't make any sense. You need an
> instantiation of Leaf - e.g. Algebraic!(Leaf!int) - rather than
> just Leaf.
My failure, I've played with the code while crafting the post.
I've used
---
alias Tree = Algebraic!(Leaf!This, NoteTypeA!This, NoteTypeB!This)
---
So no templates, just types.
> Next, you have a recursive template instantiation going on
> here. Tree depends on knowing what a NodeTypeB looks like,
> because it's using it in its instantiation of Algebraic.
> Algebraic!(Foo, Bar) is told to hold either a Foo or a Bar,
> which means that it needs to know their definitions - not just
> their names. You need to be using pointers if you want to be
> able to avoid having to know the actual definition of the type.
> So, when you tell NodeTypeB to hold a Tree when a Tree holds a
> NodeTypeB, it's impossible to figure out what the actual layout
> of those types. You have a recursive expansion.
>
> If you want to have a recursive type definition, you _must_ use
> pointers so that the actual definition of the type is not
> required.
Thing is that delegate is nothing more than a glorified pair of
pointers.
> Also, I have no idea what the deal with the This in your code
> is. IIRC, there's a feature involving This with template
> definitions, but you're just using it outside of a template
> definition, so I don't know if that's legal.
It's a recent feature of Algebraic to allow recursive
definitions. I'd assume that it uses pointers under the hood.
Older compiler but same error message: http://goo.gl/P0wmqe
More information about the Digitalmars-d-learn
mailing list