Dynamic and Static Casting

bearophile bearophileHUGS at lycos.com
Thu Feb 10 04:38:51 PST 2011


Lars T. Kyllingstad:

> Ok, bearophile's solution is better, because it has fewer casts.

And your solution was better because it's inside a function :-)


> I forgot you can cast to void*.  So here's an improved version, with some 
> template constraints to make sure it's only used for class types:
> 
>     T staticCast(T, U)(U obj)  if (is(T == class) && is(U == class))
>     {
>         return cast(T) cast(void*) obj;
>     }


And what about:

import std.stdio, std.traits, std.typetuple;

/// C++ static_cast for just down-casting
T staticDownCast(T, F)(F from) if (is(F == class) &&
                                   is(T == class) &&
                                   staticIndexOf!(F, BaseClassesTuple!T) != -1)
    in {
        assert((from is null) || cast(T)from !is null);
    } body {
        return cast(T)cast(void*)from;
    }

class Foo {}
class Bar : Foo {}
class Spam {}

Bar test1() {
    Foo f = new Foo;
    Bar b = cast(Bar)f;
    return b;
}

Bar test2() {
    Foo f = new Foo;
    Bar b = staticDownCast!Bar(f);
    return b;
}

void main() {
    Spam s = new Spam;
    Bar b = staticDownCast!Bar(s); // error
}

/*
_D4test5test1FZC4test3Bar   comdat
L0:     push    EAX
        mov EAX,offset FLAT:_D4test3Bar7__ClassZ
        mov ECX,offset FLAT:_D4test3Foo7__ClassZ
        push    EAX
        push    ECX
        call    near ptr __d_newclass
        add ESP,4
        push    EAX
        call    near ptr __d_dynamic_cast
        add ESP,8
        pop ECX
        ret

_D4test5test2FZC4test3Bar   comdat
L0:     push    EAX
        mov EAX,offset FLAT:_D4test3Foo7__ClassZ
        push    EAX
        call    near ptr __d_newclass
        add ESP,4
        pop ECX
        ret
*/


Is a pair of similar staticDownCast(), staticUpCast() fit for Phobos?

Bye,
bearophile


More information about the Digitalmars-d-learn mailing list