On Monday, March 16, 2015 22:27:36 Ali Çehreli via Digitalmars-d 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...
Defining opCast destroys basically all built-in casts, which I think is a horrible idea. The problem that you're describing was reported a couple of years ago: https://issues.dlang.org/show_bug.cgi?id=9249 But it also affects stuff like shared, and a bug report for that was created four years ago: https://issues.dlang.org/show_bug.cgi?id=5747 And there may be other bug reports for similar issues, but basically, as it stands, declaring opCast borks the built-in casts, forcing you to redefine them all, which is horrible IMHO. But Kenji expressed concern about fixing it in #5747, and no one has stepped up to sort it out. - Jonathan M Davis