On Monday, 5 March 2018 at 13:03:50 UTC, Steven Schveighoffer
wrote:
On 3/2/18 8:49 PM, Jonathan Marler wrote:
On Saturday, 3 March 2018 at 00:20:14 UTC, H. S. Teoh wrote:
On Fri, Mar 02, 2018 at 11:51:08PM +0000, Jonathan Marler via
Digitalmars-d wrote:
[...]
Not true:
template counterexample(alias T) {}
int x;
string s;
alias U = counterexample!x; // OK
alias V = counterexample!1; // OK
alias W = counterexample!"yup"; // OK
alias X = counterexample!s; // OK
alias Z = counterexample!int; // NG
The last one fails because a value is expected, not a type.
If you *really* want to accept both values and types, `...`
comes to the rescue:
template rescue(T...) if (T.length == 1) {}
int x;
string s;
alias U = rescue!x; // OK
alias V = rescue!1; // OK
alias W = rescue!"yup"; // OK
alias X = rescue!s; // OK
alias Z = rescue!int; // OK!
T
Ah thank you...I guess I didn't realize that literals like 1
and "yup" were considered "symbols" when it comes to alias
template parameters.
Well, they aren't. But template alias is a bit of a mess when
it comes to the spec. It will accept anything except keywords
AFAIK. Would be nice if it just worked like the variadic
version.
The variadic version is what is usually needed (you see a lot
of if(T.length == 1) in std.traits).
But, if you wanted to ensure values (which is more akin to your
proposal), you can do:
template rescue(alias val) if(!is(val)) // not a type
-Steve
Thanks for the tip, it looks like the spec does mention
"literals" but "alias" parameters are even more versatile than
that
(https://dlang.org/spec/template.html#TemplateAliasParameter).
For example you can pass a function call. I've created an issue
to make sure we update the spec to reflect the true capabilities:
https://issues.dlang.org/show_bug.cgi?id=18558