Problem: Cannot create class out of nothing using witchcraft

Benjamin Thaut code at benjamin-thaut.de
Wed Oct 16 07:01:41 PDT 2013


Am 16.10.2013 10:40, schrieb DoctorCaptain:
> On Wednesday, 16 October 2013 at 06:09:48 UTC, Benjamin Thaut wrote:
>> Am 16.10.2013 03:17, schrieb DoctorCaptain:
>>> I've gotten extremely close. The DPaste link that follows demonstrates
>>> three different templates:
>>>
>>> ...
>>
>> So is there any reason why you still pass the variadic arguments to
>> the generator function and not do it the way I proposed in my last
>> dpaste snippet? Even if you need the variadic arguments inside the
>> generator for some logic you could still reference them by using the
>> variadic arguments to the actual template.
>
> I suppose I was trying to give the class individual data members, such
> that passing a tuple of (WorstChild, MiddleChild, BestChild) would
> result in a class definition of:
>
> class MagicClass {
>      WorstClass t1;
>      MiddleClass t2;
>      BestClass t3;
> }
>
> However, if that is impossible (and frankly it'd be more difficult to
> work with than your way even if it was achieved), then I'll use your
> approach (actually, I'm just going to use your approach anyway. It's
> significantly cleaner than my horrid mess of a goal). That said, what is
> actually happening in your example?
>
> I reworked it a bit to demonstrate that the class has accessible members
> within T, that can be instantiated and accessed and whatnot.
>
> http://dpaste.dzfl.pl/07b20d75
>
> Note the use of typeof() to get the type of the elements at each index
> of members, to generate a type on which a constructor can be called to
> instantiate the elements at each index of members. Magic.
>
> What is T within the generated class definition? Is this just how tuples
> work? T is an "array" of three arbitrary pointers, initially null, that
> can be instantiated with new to create valid pointers to objects of each
> type at T's indexes? Like, T in the DPaste example is an array of
> pointers, such that:
> [WorstChild*, MiddleChild*, BestChild*]? Is it literally just magic like
> that?
>
> Actually, let me formally present a couple of ending thoughts/questions:
>
> First, allow me to apologize for trying to force a different, messy
> horrid mess of a goal on you, when your initial solution was majestic to
> begin with.

No problem, I can understand that you want to stick with your solution. 
But as Artur explained the template is actually not able to see the 
actual types directly and thats why full qualified identifier will not work.

>
> Second, as I was trying to figure out just a moment ago, what -exactly-
> is T in the generated class definition, and why does it allow me to use
> it as an arbitrary container for objects of the arbitrary types I want
> it to contain (Read: why is it able to do exactly what I want it to be
> able to do? What's going on behind the scenes?)?

T is the variadic argument T that is passed to the actual template 
"GrabBagT". It might become more clear when actually copy & pasting the 
generated code into the template. The problem is that you try to 
reference the classes by name. Thats not necessary. You get the classes 
passed in as template arguments. So you just reference them as template 
arguments instead of referencing them by name. It is possible to do so 
by not generating access via the name but instead use the template 
arguments passed to GrabBagT. I hope this made it a bit more clear. I 
might have some more time later today to look into your new examples and 
modify them.

>
> Third, given that I am going to go with your solution (it works, it
> works well, and I can't seem to force my original goal to work, whether
> that was even a good idea to begin with at all (it wasn't)), can you
> think of a way to actually produce my original goal? That is, instead of
> a container T which I can use to access my arbitrary data members once
> the generated class is instantiated, is it actually even possible to
> generate individual data members, a la:
>
> class MagicClass {
>    T[0] t0;
>    T[1] t1;
>    // ... etc
> } // ?

What do you need individual data members for? In my example the "T 
members" is actually a instance of a tuple which actually comes down to 
the exakt same data layout like individual data members. The only 
difference is that you access them by index and not by name. Which is 
actually a plus if you ask me for generic programming. You can even get 
back the tuple by doing typeof(members);

>
> You've been wildly helpful, and admirably concise. I am -extremely-
> interested in the answer to the second thought, and while I'm sure the
> answer is simple, it also seems -too- magic to actually work, and yet it
> does.
>
> Again, thank you to everyone who responded, and thank you Benjamin for
> your continued help.

No problem. I love the metaprogramming abilities of D and a occansional 
challenge is always welcome ;-)

-- 
Kind Regards
Benjamin Thaut


More information about the Digitalmars-d-learn mailing list