Overloading opCast with multiple types

Kristian kjkilpi at gmail.com
Sun Oct 1 04:30:09 PDT 2006


On Sun, 01 Oct 2006 01:25:15 +0300, Reiner Pope  
<reiner.pope at REMOVE.THIS.gmail.com> wrote:
> As we all know, opCast can only have one overload per class, because D  
> doesn't support overloading by return type. That is a really silly  
> limitation, in my opinion. Anyway, I have a solution here: give it a  
> parameter, which is the type (we pass this parameter in the form of a  
> template). Here's the magic:
>
> class Test
> {
> 	int x;
> 	Foo myCast(TFoo : Foo)() { static assert(is(TFoo == Foo), "No cast of  
> the required type exists"); return new Foo(x); }
> 	Bar myCast(TBar : Bar)() { static assert(is(TBar == Bar),  "No cast of  
> the required type exists"); return new Bar(x); }
> 	FooExtender2 myCast(T : FooExtender2)() { static assert(is(T ==  
> FooExtender2), "No cast of the required type exists"); return new  
> FooExtender2(x); }
> 	this(int _x) {x = _x;}
> }
[snip]

Actually I was thinking something similar a while ago. Then I thought that  
maybe there is only one opCast() for a reason. And you could use functions  
as 'toString()' to do the casting (but, yeah, that's explicit).

Anyway, I think the opCasts can also be implemented as follows:

class Obj {
     int opCast(out int dst) {return(dst = ...);}
     Foo opCast(out Foo dst) {return(dst = ...);}
}

Or in some other way which don't complicate the implementation of  
compilers. (Of course, the previous syntax makes it cumbersome to call  
opCasts by yourself (e.g. "obj.opCast(tmp);"), but you're supposed to use  
cast statements anyway (e.g. "cast(int)obj").)


Finally I have to say that I think the implicit type casting in C++ could  
work better. For example:

class String {
     operator int() const;
     operator char *() const;
};

void func(int v);
void func(char *s);

String s;
func(s);  //error: ambigious call

Because 'String' can be casted to 'int' and 'char *', the compiler don't  
know which one to use. Of course, 's' should be casted to 'char *' because  
the class represents a string (i.e. 'char *').

This could be solved by using some kind of preference ordering. For  
example (don't pay attention to the syntax):

class String {
     preference 2 operator int() const;
     preference 1 operator char *() const;  //prefer 'char *' over 'int'
};

So, if D will have multiple opCasts along with the implicit type  
conversion, maybe something similar could be used to solve problems with  
implicit casting.



More information about the Digitalmars-d mailing list