The most awesome "forward to member" solution?

Andrei Alexandrescu via Digitalmars-d digitalmars-d at puremagic.com
Sun May 3 11:54:56 PDT 2015


On 5/3/15 12:18 AM, Meta wrote:
> On Sunday, 3 May 2015 at 05:49:52 UTC, Andrei Alexandrescu wrote:
>> On 5/2/15 10:00 PM, Meta wrote:
>>> It seems like it'd be a lot cheaper and cleaner to just be able to alias
>>> the parent method.
>>
>> Yeh, that's the first solution that comes to mind. alias doesn't work
>> here but of course we could change the language.
>>
>>> Also, it could probably be made a bit simpler with
>>> opDispatch.
>>
>> I'd have to see the code, but my intuition is that things could get
>> quite a bit more hairy.
>>
>>
>> Andrei
>
> IMO, using __traits and opDispatch is a fair bit cleaner, and I prefer
> the syntax of a mixin template to regular mixin.
>
> http://dpaste.dzfl.pl/d60498246577

You're right, that is lovely! I've improved it as follows:

mixin template forwardToMember(alias member, methods...)
{
     import std.algorithm : among;
     import std.traits : ParameterTypeTuple;
     template opDispatch(string sym)
     if ((methods.length == 0 || sym.among(methods)))
     {
         auto ref opDispatch(
             ParameterTypeTuple!(__traits(getMember, member, sym)) args)
         {
             return __traits(getMember, member, sym)(args);
         }
     }
}

So now ref returns are preserved and the mixin is self-contained 
(doesn't require imports from the outside).

Compared to my solution, this has the advantage that if the child 
defines a method, it will take precedence over the formatted one. So 
that allowed me to add a feature: if no methods are specified, all are 
forwarded.

There are a couple of ways in which this could and should be improved, 
most notably overloads control. Even as is it's pretty darn awesome, 
Meta could you please make it into a pull request? I think it should go 
in std.functional.


Andrei



More information about the Digitalmars-d mailing list