digitalmars.D.learn - alias parameter tuples: need this to access member
- Tobias Pankrath (24/24) May 26 2012 I am writing a mixin template that uses alias parameters and
- Philippe Sigaud (86/107) May 26 2012 th
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
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=thusing 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 =atonce. 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 memberOK, 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