On Wednesday, 6 November 2013 at 13:00:17 UTC, Atila Neves wrote:
The title isn't very clear but I wasn't sure how to phrase it without code. Basically what I want to do is this (won't compile):

struct Foo(int N) {
}

void func(T)(T obj) if(is(T:Foo)) {
}

void func(T)(T obj) if(!is(T:Foo)) {
}

Foo by itself isn't a type, but I don't want to limit func instantiation in the 1st case to just e.g. Foo!3 but to _any_ Foo regardless of N. I came up with two workarouds: make Foo a class that derives from an empty FooBase (then is(T:FooBase) works), or adding a "secret" enum within Foo that I can check with std.traits.hasMember in a static if. I don't really like either of them. Is what I want to do possible?

Atila

Here's a couple of different ways to do this.

    import std.stdio;

    struct Foo(int N) {
    }

    void func(T)(T obj) if(is(T:Foo!U, int U)) {
        writeln("It's a Foo!");
    }

    void func(T)(T obj) if(!is(T:Foo!U, int U)) {
        writeln("No Foo :(");
    }

    template isFoo(T) {
        static if(is(T:Foo!U, int U))
            enum isFoo = true;
        else
            enum isFoo = false;
    }

    void gunc(T)(T obj) if(isFoo!T) {
        writeln("Gunc isFoo");
    }

    void gunc(T)(T obj) if(!isFoo!T) {
        writeln("Gunc !isFoo");
    }

    void hunk(T)(T obj) {
        static if(isFoo!T)
            writeln("Hunk!");
        else
            writeln("No hunk!");
    }

    void main() {
        Foo!3 f;
        func(f); // It's a Foo!

        struct S {}
        S s;
        func(s); // No Foo :(

        gunc(f); // Gunc isFoo
        gunc(s); // Gunc !isFoo

        hunk(f); // Hunk!
        hunk(s); // No hunk!
    }

Reply via email to