Implicit conversion from array of class to array of interface

Phil Deets pjdeets2 at gmail.com
Sun Dec 13 01:08:19 PST 2009


On Sun, 13 Dec 2009 03:22:31 -0500, Phil Deets <pjdeets2 at 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);
	}
}


More information about the Digitalmars-d-learn mailing list