On Sun, 13 Dec 2009 03:22:31 -0500, Phil Deets <pjdee...@gmail.com> wrote:

(D 2.033) I have a need to do something like this code:

interface I {}
class C : I {}
class D : I {}

void f(I[]) {}
void f(bool) {}

void g(T)(T param) {
        f(param);
}

int main()
{
        bool b;
        C[] c;
        D[] d;
        g(b);
        g(c);
        g(d);
        return 0;
}

This results in the output:

temp.d(9): Error: function temp.f (I[] _param_0) is not callable using argument types (C[]) temp.d(9): Error: cannot implicitly convert expression (param) of type C[] to bool
temp.d(18): Error: template instance temp.g!(C[]) error instantiating

As you can see, I can't cast C[] to I[] when I call f because T can be bool too. My workaround for now is:

interface I {}
class C : I {}
class D : I {}

void f(I[]) {}
void f(C[] param) {
        f(cast(I[])param);
}
void f(D[] param) {
        f(cast(I[])param);
}
void f(bool) {}

void g(T)(T param) {
        f(param);
}

int main()
{
        bool b;
        C[] c;
        D[] d;
        g(b);
        g(c);
        g(d);
        return 0;
}

Is there a better way to deal with this? Is this behavior a design bug?

Phil Deets


I found another workaround which doesn't require a bunch of extra overloads. I'll probably update it to use that template someone wrote in that thread about static duck-typing.

//interface I {void h();}
class C /*: I*/ {void h() {}}
class D /*: I*/ {void h() {}}

void f(T)(T param)
{
        static if (__traits(compiles, param[0].h()))
        {
                // do I[] overload here
        }
        else
        {
                pragma(msg, "Unsupported type for f.")
                static assert(0);
        }
}
void f(T:bool)(T param) {}

void g(T)(T param) {
        f(param);
}

int main()
{
        bool b;
        C[] c;
        D[] d;
        g(b);
        g(c);
        g(d);
        return 0;
}

By the way, how do I move the bool specialization into the general function?

void f(T)(T param)
{
        static if (__traits(compiles, param[0].h()))
        {
                // do I[] overload here
        }
        else static if (T is bool) // how do I do this?
        {
        }
        else
        {
                pragma(msg, "Unsupported type for f.")
                static assert(0);
        }
}

Reply via email to