On Mon, Sep 6, 2010 at 23:31, Andrej Mitrovic <andrej.mitrov...@test.com>wrote:
> That still won't work. Observe: > template isInputRange(R) > { > enum bool isInputRange = isValidCode!( > { > R r; // can define a range object > if (r.empty) {} // can test for empty > r.popFront; // can invoke next > auto h = r.front; // can get the front of the range > }); > } > > template isValidCode(alias code) { enum bool isValidCode = > __traits(compiles, code); } > > Instead of returning false, it will give out a compiler error. > That's because the part between the curly braces is evaluated before being passed to the template. And there is no lazy alias. As Mafi said, you can use a string, it's still the best way to move code around in D. With q{ ... }, it's palatable. And no, before you try it, there is no way to pass the {...} to another template that would stringify it into a q{...} :-) Maybe, eventually, something like this: import std.stdio; template isValidCode(alias code) { template For(T) { enum bool For = __traits(compiles, code(T.init)); } } void main() { // use an anonymous templated function: alias isValidCode!((r) { if (r.empty) {} // can test for empty r.popFront; // can invoke next auto h = r.front; // c } ) isInputRange; // writeln(isInputRange.For!(int[])); } Except DMD doesn't like the commented-out line. Whaoh! Philippe