Defining a single opCast disables explicit cast to base interfaces

jkpl via Digitalmars-d digitalmars-d at puremagic.com
Tue Mar 17 00:07:34 PDT 2015


On Tuesday, 17 March 2015 at 05:27:38 UTC, Ali Çehreli wrote:
> The following program compiles fine:
>
> interface I
> {}
>
> class B : I
> {}
>
> class C : B
> {
>     int i;
> }
>
> void main()
> {
>     auto c = new C;
>
>     auto i = cast(I)c;    // compiles
>     auto b = cast(B)c;    // compiles
> }
>
> Let's add an unrelated opCast to C:
>
> class C : B
> {
>     int i;
>
>     int opCast(T : int)()
>     {
>         return i;
>     }
> }
>
> Now the last two lines of main fail to compile:
>
> Error: template instance opCast!(I) does not match template 
> declaration opCast(T : int)()
> Error: template instance opCast!(B) does not match template 
> declaration opCast(T : int)()
>
> Is this per spec? (Actually, where is the spec? (Trick 
> question. ;) )
>
> There is a workaround: Add a catch-all opCast that forwards to 
> the all-powerful std.conv.to:
>
>     T opCast(T)()
>     {
>         import std.conv;
>         return this.to!T;
>     }
>
> Now it compiles and works as expected.
>
> However, the question remains...
>
> Thank you,
> Ali

There is also another trick: generally when something cannot be 
cast then it's often possible to cast it as a pointer to the cast 
type that is directly derefered. And it work...
---
     T opCast(T)()
     {
         static if(is(T==int))
             return i;
         else
             return *cast(T*) &this;
     }
---

...ed until version 2.067 (now it's deprecated because of &this 
since this is already a ptr).


More information about the Digitalmars-d mailing list