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