www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - alias parameter tuples: need this to access member

reply "Tobias Pankrath" <tobias pankrath.net> writes:
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.

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

How can I do this? Thank you in advance :)
May 26 2012
parent Philippe Sigaud <philippe.sigaud gmail.com> writes:
On Sat, May 26, 2012 at 12:39 PM, Tobias Pankrath <tobias pankrath.net> wro=
te:
 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 wi=

 using multiple aliases as a tuple.

 This works:

 mixin template print(alias x) {
 =C2=A0 =C2=A0void 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 =

 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...)
 {
 =C2=A0 =C2=A0void doprint() {
 =C2=A0 =C2=A0 =C2=A0 =C2=A0foreach(mem; b)
 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0writeln(b);
 =C2=A0 =C2=A0}
 }

 class A { int x,y; mixin print!(x, y); }

 Now DMD says: =C2=A0need 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 =3D " void doprint() { writeln("; foreach(i,member;a) result ~=3D 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 =3D new A(); auto b =3D new B(); auto c =3D 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
May 26 2012