3
votes

D2.056

Function is a struct holding the name and the type of the function (Name and Type respectively). Binds iterates over a list of Function structs and returns a mixin string. This mixin defines for each function a new name with a '2' appended.

void f() { writeln("f"); }
void g() { writeln("g"); }

struct Function(string name, Prototype)
{
    const string Name = name;
    mixin("alias Prototype Type;");
}

string Binds(Functions...)()
{
    string r;
    foreach (F; Functions)
    {
        // error:
        r ~= to!string(typeid(F.Type)) ~ " " ~ F.Name ~ "2 = &" ~ F.Name ~ ";";
    }
    return r;
}

int main()
{
    mixin (Binds!(
                 Function!("f", void function()),
                 Function!("g", void function())        
                 ));

    f();
    //f2();

    return 0;
}

When compiling, the to!string(typeid(F.Type)) gives an error:

Error: Cannot interpret & D13TypeInfo_PFZv6__initZ at compile time
   called from here: to(& D13TypeInfo_PFZv6__initZ)
   called from here: Binds()

Firstly, I don't see why an explicit conversion to string is required (isn't typeid already a string, if not, whats the difference between typeid and typeof?).

Secondly, I can't figure out how to get the explicit function type written out so that it can be executed in main. I can't use F.Type since it is local to the foreach.

1

1 Answers

2
votes

You've got a couple problems here, but the main one is that typeid returns an object of type TypeInfo (typeid expression). Fortunately, you can just use F.Type.stringof. Also note that you don't need the mixin to alias Prototype as Type:

void f() { writeln("f"); }
void g() { writeln("g"); }

struct Function(string name, Prototype)
{
    const string Name = name;
    alias Prototype Type;
}

string Binds(Functions...)()
{
    string r;
    foreach (F; Functions)
    {
        // error:
        r ~= F.Type.stringof ~ " " ~ F.Name ~ "2 = &" ~ F.Name ~ ";";
    }
    return r;
}

import std.stdio,
    std.conv;
int main()
{
    mixin (Binds!(
                 Function!("f", void function()),
                 Function!("g", void function())        
                 ));

    f();
    f2();

    return 0;
}

Running this prints:

f
f

which I believe is what you're looking for.