On Saturday, 13 June 2015 at 10:01:45 UTC, JDemler wrote:
Hey,

i am trying to wrap my head around __traits.

One thing i just do not understand is following:

struct S{
   string member1;
   int member2;
}

void main(string[] args)
{
   foreach(typeStr; __traits(allMembers, S))
   {
     auto tp = __traits(getMember, S, typeStr);
     static if (__traits(isArithmetic, tp))
       writeln(typeStr ~ " is Arithmetic");
   }
}

Does not compile. "main.d(15): Error: need 'this' for 'member1'
of type 'string'"

But if the inner part of the foreach-loop is changed to:

static if (__traits(isArithmetic, __traits(getMember, S,
typeStr)))
       writeln(typeStr ~ " is Arithmetic");

it compiles and does exactly what i expect it to do.

If i understand it correctly __traits(getMember returns a
reference to that member, so i get why i shouldn't be able to use
it with the class instead of an instance of a class.

But why does it work if it is nested inside a __traits call?

Try `alias` instead of `auto`:

    struct S{
       string member1;
       int member2;
    }

    alias I(Args...) = Args;

    void main(string[] args)
    {
       import std.stdio;
       foreach(typeStr; __traits(allMembers, S))
       {
         alias tp = I!(__traits(getMember, S, typeStr));
         static if (__traits(isArithmetic, tp))
           writeln(typeStr ~ " is Arithmetic");
       }
    }

`auto` declares a variable, which in this case will probably contain a delegate to that member.

The workaround with `I` is needed because of a syntactic limitation: `alias tp = __traits(...);` is currently not allowed by the grammar.

Reply via email to