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

Reply via email to