Perfect forwarding

Jean-Louis Leroy jl at leroy.nyc
Sun Jul 26 18:14:03 UTC 2020


On Sunday, 26 July 2020 at 01:29:21 UTC, Andrei Alexandrescu 
wrote:
> This topic came about during beerconf (it was fun!): Write an 
> idiomatic template `forward` that takes an alias `fun` and 
> defines (generates) one overload for each overload of `fun`. 
> Example:
>
> template forward(alias fun)
> {
>     ...
> }
>
> Now for this function:
>
> void myfun(int, ref double, out string);
> int myfun(in string, inout double);
>
> the instantiation would be (stylized):
>
> template forward!myfun
> {
>     void myfun(int a, ref double b, out string c)
>     {
>         return myfun(a, b, c);
>     }
>     int myfun(in string a, inout double b)
>     {
>         return myfun(a, b);
>     }
> }
>
> So the challenge is implementing forward() to do this.

Using bolts' experimental refraction module:

module challenge;

import std.format;
import bolts.experimental.refraction;

template forward(alias fun)
{
     enum name = __traits(identifier, fun);
     static foreach (ovl; __traits(getOverloads, __traits(parent, 
fun), name)) {
         mixin(
             {
                 enum original = refract!(ovl, "ovl");
                 return original.withBody(q{{
                             return %s(%s);
                         }}.format(original.name, 
original.argumentMixture))
                     .mixture;
             }());
     }
}

void myfun(int, ref double, out string);

int myfun(in string, inout double);

pragma(msg, typeof(__traits(getOverloads, forward!myfun, 
"myfun")[0]));
pragma(msg, typeof(__traits(getOverloads, forward!myfun, 
"myfun")[1]));

Output:

@system void(int _0, ref double _1, out string _2)
@system int(const(string) _0, inout(double) _1)

Okay the "in" is missing in front of the first argument of the 
second overload, but it doesn't seem to be there in the first 
place:

pragma(msg, typeof(__traits(getOverloads, challenge, 
"myfun")[1]));

Output:
int(const(string), inout(double))

Also the body of the forwarders should probably use 
`std.functional.forward`.


More information about the Digitalmars-d mailing list