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