__traits getMember is context sensetive?
via Digitalmars-d-learn
digitalmars-d-learn at puremagic.com
Sat Jun 13 03:26:04 PDT 2015
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.
More information about the Digitalmars-d-learn
mailing list