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

Reply via email to