On Thursday, 7 April 2016 at 20:31:12 UTC, jmh530 wrote:
I've been playing around with __traits and I find myself confused on one aspect. In the code below, I was testing whether some templates would compile given types. For the most part it works as I would expect.

I think I get why the third one works with foo!(int). My guess is that it assumed that U is the same as T and both are int. However, that wouldn't make sense with the last one where I use bar!(int). In that one it's basically ignoring the second template constraint. So I don't understand what's going on for that last line to compile. To confirm I wasn't crazy, I get an error with
alias bar_ = bar!(int);



import std.traits : isNumeric;
import std.range : isInputRange;

void foo(T, U)(T x, U y) if (isNumeric!T && isNumeric!U) { }

void bar(T, U)(T x, U y) if (isNumeric!T && isInputRange!U) { }

void main()
{
        assert(__traits(compiles, foo!(int, int)));     //I get this
        assert(!__traits(compiles, foo!(bool, bool)));  //I get this
        assert(__traits(compiles, foo!(int)));          //I think I get this
        assert(__traits(compiles, bar!(int, int[])));   //I get this
        assert(!__traits(compiles, bar!(int, int)));    //I get this
        assert(__traits(compiles, bar!(int)));          //I don't get this
}

Neither the third nor sixth lines should be true.

alias wrongfoo = foo!int; /* Error: template instance foo!int does not match template declaration foo(T, U)(T x, U y) if (isNumeric!T && isNumeric!U) */
    alias rightfoo = foo!(int, int); /* ok */

File a DMD bug.

(Also, you can use static assert here to check the assertions at build-time instead of run-time)

Reply via email to