opCast in class prevents destroy

vit vit at vit.vit
Tue Mar 1 08:51:00 UTC 2022

On Tuesday, 1 March 2022 at 08:16:13 UTC, Mike Parker wrote:
> On Tuesday, 1 March 2022 at 07:16:11 UTC, bauss wrote:
>> Right now if you want to add an additional cast then you have 
>> to implement ALL the default behaviors and then add your 
>> custom cast.
> It's two template functions like the OP used: one for T to 
> catch everything, and one specialization.
>> That doesn't seem correct to me at least.
> Depends on your perspective I guess. For the inverse, when you 
> want to allow only one kind of cast and prevent everything 
> else, you only have to implement one template right now. If 
> that were not the case, then you'd have to implement an 
> additional catch-all template that bombs out with a static 
> assert.
> So either way makes sense, IMO. Though I totally understand how 
> the current behavior can be a surprise when people expect it to 
> behave like, e.g., C++.
> But D is not C++. So is `opCast` intended to expand the list of 
> target types (like C++), or is it intended to define it? The 
> spec says, "To define how one type can be cast to another", 
> which doesn't really answer the question.

Now is possible this:

import std.stdio;

     struct Foo{
         int i;

         this(int i)@safe{
         	this.i = i;
             writeln("ctor(", i, "): ", cast(void*)&this);

         Foo opCast(T, this This)()@safe
         if(is(immutable T == immutable This)){
             return Foo(2);

         	writeln("dtor(", i, "): ", cast(void*)&this);

     struct Bar{
         const Foo foo;

         this(int i)@safe{
         	this.foo = Foo(i);

     void main()@safe{
         Bar bar =  Bar(1);

ctor(1): 7FFE0D5A94A8  //dtor for Foo(1) is never called.
ctor(2): 7FFE0D5A9410
dtor(2): 7FFE0D5A9470
dtor(2): 7FFE0D5A9470  //dtor for Foo(2) is called twice.

More information about the Digitalmars-d-learn mailing list