std.typecons.Proxy + inheritance breaks cast'ing to inherited type

anonymous via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Tue Mar 17 16:58:22 PDT 2015


On Tuesday, 17 March 2015 at 07:56:19 UTC, Ali Çehreli wrote:
> > Why can't you do this instead?
> >
> > t opCast(t)()
> > if (is(typeof(cast(T)this)))
> > {
> >      return cast(T)this;
> > }
>
> That has the same problem: 'cast(T)this' happens to be an 
> explicit cast, which is disabled by the opCast overload for int.
>
> Ali

For classes, `T opCast(T)() {return cast(T) super;}` may be 
viable.

For structs, it's seems more difficult to me.

`return this.to!T;` may try a cast(T), so it has the same problem 
as `return cast(T) this;`: infinite recursion. Example:
----
struct StdConvTo
{
     int* p;
     int opCast(T : int)() {return 42;}
     T opCast(T)() {import std.conv; return this.to!T;}
}
unittest
{
     assert((cast(int) StdConvTo()) == 42); /* ok */
     auto i = cast(immutable StdConvTo) StdConvTo(); /* infinite 
recursion */
}
----
This applies to classes, too.

A reinterpret cast would allow casts that should be rejected:
----
struct Reinterpet
{
     int* p;
     int opCast(T : int)() {return 42;}
     T opCast(T)() {return * cast(T*) &this;}
}
unittest
{
     assert((cast(int) Reinterpet()) == 42); /* ok */
     auto s = cast(float) Reinterpet(); /* compiles, but shouldn't 
*/
}
----

Here's something that might work. Construct a "tuple" of the 
struct's fields (i.e. same data but no opCast). Then cast that to 
T.
----
struct TupleOf
{
     int* p;
     int opCast(T : int)() {return 42;}
     T opCast(T)()
     {
         static struct Tuple(S) {S stuff;}
         static Tuple!S tuple(S)(S stuff) {return Tuple!S(stuff);}
         return cast(T) tuple(this.tupleof);
     }
}
unittest
{
     assert((cast(int) TupleOf()) == 42); /* ok */
     auto i = cast(immutable TupleOf) TupleOf(); /* ok */
     static assert(!__traits(compiles, cast(float) TupleOf())); /* 
ok */
}
----
This is probably not perfect either.


More information about the Digitalmars-d-learn mailing list