alias parameter tuples: need this to access member
Philippe Sigaud
philippe.sigaud at gmail.com
Sat May 26 06:31:51 PDT 2012
On Sat, May 26, 2012 at 12:39 PM, Tobias Pankrath <tobias at 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
More information about the Digitalmars-d-learn
mailing list