opCast in class prevents destroy

Mike Parker aldacron at gmail.com
Tue Mar 1 04:59:49 UTC 2022


On Tuesday, 1 March 2022 at 04:29:56 UTC, cc wrote:
> ```d
> struct A {}
> class B {
> 	A opCast(T : A)() {
> 		return A();
> 	}
> }
> void main() {
> 	auto b = new B();
> 	destroy(b);
> }
> ```
> fails with
> ```
> dmd2\windows\bin\..\..\src\druntime\import\object.d(4209): 
> Error: template instance `opCast!(void*)` does not match 
> template declaration `opCast(T : A)()`
> main.d(9): Error: template instance `object.destroy!(true, B)` 
> error instantiating
> ```
>
> Looks like a similar bug has been reported: 
> https://issues.dlang.org/show_bug.cgi?id=22635

Is it a bug? It's not documented in the `opCast` documentation, 
but it looks like when you define an `opCast` it completely 
replaces the default behavior, i.e., whatever type you define as 
the target type becomes the only type to which you can attempt to 
cast.

It makes sense to me, and I would say the bug is that it's not 
documented.

>
> As a workaround, adding an additional opCast:
> ```d
> class B {
> 	A opCast(T : A)() {
> 		return A();
> 	}
> 	auto opCast(T)() {
> 		return cast(T)super;
> 	}
> }
> ```
> SEEMS to work.  Is that safe?  Or are consequences not what I'm 
> intending?

So what you've done here is specialized on anything convertible 
to `A` and then reenabled casts to all other types, i.e., the 
default behavior, but with a special exception for `T:A`.

You could also specialize on `void*`, as that's the type that was 
failing to compile. Then you're restricted to `void*` and 
anything convertible to `A`.




More information about the Digitalmars-d-learn mailing list