On Sat, May 26, 2012 at 12:39 PM, Tobias Pankrath <tob...@pankrath.net> wrote:
> I am writing a mixin template that uses alias parameters and should me
> instantiated in a class. With only one parameter, it works. But I fail with
> using multiple aliases as a tuple.
>
> This works:
>
> mixin template print(alias x) {
>    void doprint() { writeln(x); }
> }
>
> class A { int x; mixin print!x; }
>
> Now I would like to do the same, but with several attributes of my class at
> once. Thus I tried tuple parameters:
>
> mixin template print(alias b...) { ... } // seem not to be legal syntax.

No, the legal syntax is indeed b..., as you use below. Normally, all
members of b should be aliases. Seems like a bug to me, but perhaps
people knowing the compiler internals better than us could answer.


>
> My second try was this:
>
> mixin template print(b...)
> {
>    void doprint() {
>        foreach(mem; b)
>            writeln(b);
>    }
> }
>
> class A { int x,y; mixin print!(x, y); }
>
> Now DMD says:  need this to access member

OK, here is a module that works:

module test;

import std.stdio;
import std.conv;

mixin template print(alias x)
{
   void doprint()
   {
       writeln(x);
    }
}

// same as you
class A
{
    int x;
    mixin print!x;
}

// extracting aliases one by one. No loop, but recursion
mixin template print2(alias a, rest...)
{
    void doprint()
    {
        writeln(a);
        static if (rest.length > 0) // still other aliases to extract
            mixin print2!(rest);
   }
}

class B
{
    int x,y;
    mixin print2!(x,y);
}

// Another solution, maybe more generic: string mixins
string print3(a...)() @property
{
    // We begin by assembling the desired final code, as a string
    string result = "
    void doprint()
    {
        writeln(";
    foreach(i,member;a)
        result ~= member ~ (i<a.length-1 ? ", " : "");
    return result ~ ");
    }";
}

class C
{
    int x,y;
    mixin(print3!("x","y")); // see the ( ) after mixin, and the
members are passed as strings
}

void main()
{
    auto a = new A();
    auto b = new B();
    auto c = new C();

    a.doprint();
    b.doprint();
    c.doprint();
}

I tried the string mixin version with (b...) (enabling a call like
this:  mixin(print3!(x,y)); ), but I got the same error as you.

Btw, it's possible to extract members of a class inside the mixin with
__traits(allMembers, typeof(this)) and to automate the process
somewhat:

mixin template print4()
{
    void doprint()
    {
        writeln([__traits(allMembers, typeof(this))]);
    }
}

class D
{
    int x,y;
    double z;
    mixin print4;
}

Philippe

Reply via email to