[static] foreach scope, template declaration ?

Mathias LANG via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Thu Sep 25 15:11:19 PDT 2014


I'm a bit puzzled with the following behavior:

----
import std.typetuple, std.traits;

struct UDAStruct {
     string identifier;
}

class MyClass {
     @(UDAStruct("p1"), UDAStruct("p2"), UDAStruct("P3")) // P3 is 
a typo
       void func(int p1, string p2, float p3) {}
}

unittest {
     alias Func = MyClass.func;
     enum ParamNames = ParameterIdentifierTuple!Func;
     enum ParamAttr = __traits(getAttributes, Func);

     foreach (attr; ParamAttr) {
         template CmpName(string PName) {
             pragma(msg, "Instantiated for: "~PName);
             enum CmpName = (PName == attr.identifier);
         }
         pragma(msg, "Current attr is: "~attr.identifier);
         static assert(anySatisfy!(CmpName, ParamNames));
     }

     // Foreach does introduce a scope, as this produce no compile 
time error.
     template CmpName(string test) { enum CmpName = test; }
     static assert(CmpName!"?" == "?");
}

void main() {}
----

The output is (FE 2.066 & 2.065 tested):
148 geod24 at barsoom2 ~ % dmd -unittest -run test.d
Current attr is: p1
Instantiated for: p1
Instantiated for: p2
Instantiated for: p3
Current attr is: p2
Current attr is: P3

Obviously one call tell it's not what I expected. It looks like 
DMD is reusing the instantiations of the template of the first 
loop for p2 and P3.
The 2 lines at the end check that foreach does introduce a scope, 
but it behaves differently than what we're use to.

Is there a way around this ?
I tried to move CmpName outside the loop, then declare `alias 
Cmp(string x) = CmpName(attr, x);` in the loop, but it doesn't 
help (I guess the same thing happens?).


More information about the Digitalmars-d-learn mailing list