Thread overview
Template constraint on alias template parameter.
Aug 06, 2020
jmh530
Aug 06, 2020
jmh530
Aug 06, 2020
ag0aep6g
Aug 06, 2020
jmh530
August 06, 2020
The code below compiles, but I want to put an additional constraint on the `test` function is only called with a Foo struct.

I tried things like is(T == Foo) and is(T : Foo), but those don't work. However, something like is(T!int : Foo!int) works, but is(T!U == Foo!U, U) doesn't. Any idea why is(T!U == Foo!U, U) doesn't work?

struct Foo(T)
{
    T x;
}

void test(alias T)()
    if (__traits(isTemplate, T))
{
    import std.stdio: writeln;
    writeln("there");
}

void main()
{
    test!Foo();
}

August 06, 2020
On Thursday, 6 August 2020 at 16:01:35 UTC, jmh530 wrote:
> [snip]

It seems as if the T is properly Foo(T) and can only be instantiated with actual types. Something like below works and might work for me.

template test(alias T)
    if (__traits(isTemplate, T))
{
    void test(U)(U x)
        if (is(T!U : Foo!U))
    {
        import std.stdio: writeln;
        writeln("there");
    }
}
August 06, 2020
On Thursday, 6 August 2020 at 16:01:35 UTC, jmh530 wrote:
> The code below compiles, but I want to put an additional constraint on the `test` function is only called with a Foo struct.
>
> I tried things like is(T == Foo) and is(T : Foo), but those don't work. However, something like is(T!int : Foo!int) works, but is(T!U == Foo!U, U) doesn't. Any idea why is(T!U == Foo!U, U) doesn't work?
>
> struct Foo(T)
> {
>     T x;
> }
>
> void test(alias T)()
>     if (__traits(isTemplate, T))
> {
>     import std.stdio: writeln;
>     writeln("there");
> }
>
> void main()
> {
>     test!Foo();
> }

`is(...)` only works on types. You're looking for `__traits(isSame, T, Foo)`.

For `is(T!U == Foo!U, U)` to work, the compiler would have to guess U. If the first guess doesn't work, it would have to guess again, and again, and again, until it finds a U that does work. Could take forever.
August 06, 2020
On Thursday, 6 August 2020 at 18:09:50 UTC, ag0aep6g wrote:
> [snip]
>
> `is(...)` only works on types. You're looking for `__traits(isSame, T, Foo)`.
>
> For `is(T!U == Foo!U, U)` to work, the compiler would have to guess U. If the first guess doesn't work, it would have to guess again, and again, and again, until it finds a U that does work. Could take forever.

Thanks for the explanation!