Re: [Boost-Users] Re: boost::polymorphic_upcast suggestion

Sorry, don't know what happened then, I'll continue... class A {}; class B {}; class C : public A, public B {}; int main(int argc, char* argv[]) { C c; C* pc = &c; //B* pb = boost::polymorphic_downcast<B*>( pc ); // this cast is unnecessary, the compiler <knows> that C isa B at compile time, // so it can go ahead and upcast it without asking you or the runtime type info: B* pb = pc; // C* pc2 = polymorphic_upcast<C*>( pb); // this is precisely where the boost::polymorphic_downcast is intended to be used, // ie Cast a Base (ptr or ref) to a Derived (ptr or ref) // the compiler doesn't know that a B object is definately a valid C, so it requires you to // qualify it, using some kind of cast. C* pc2 = boost::polymorphic_downcast<C*>(pb); return 0; } So thats downcasting and upcasting, there is no need for a polymorphic_upcast, as it is implicity done and can be tested for at compile time. The only other cast not covered here is cross casting, which is what boost::polymorphic_cast is designed for, but I find that almost everytime I come across a use of a cross cast it is due to a design flaw. (the same could also be said to a lesser extent about downcasting) Hope this clears things up a bit. Sam
-----Original Message----- From: news [mailto:news@main.gmane.org]On Behalf Of Jean Llorca Sent: 27 June 2002 15:31 To: boost-users@yahoogroups.com Subject: [Boost-Users] Re: boost::polymorphic_upcast suggestion
"Darin Adler" <darin@bentspoon.com> a écrit dans le message de news: B586F909-89D7-11D6-9349-0003935B80A2@bentspoon.com...
On Thursday, June 27, 2002, at 06:38 AM, Jean Llorca wrote:
Here upcasting means casting a base class to a derived class, I know it may seem strange, bust boost offers a downcast which does the static_cast the language does implicitly
already (check
<boost/cast.hpp>).
I think you've got it backwards. Downcasting, in Boost at least, means casting a pointer to a base class part of an object to a pointer to a derived class part of the same object. The polymorphic_downcast is *not* doing a static_cast for a conversion the language already does implicitly.
template <class Target, class Source> inline Target polymorphic_downcast(Source* x BOOST_EXPLICIT_DEFAULT_TARGET) { assert( dynamic_cast<Target>(x) == x ); // detect logic error return static_cast<Target>(x); }
Sorry about it, but it's here in the code. This is in the last version of the CVS. It does a static_cast. The compiler does static_cast implicitly in some cases. For instance a C++ compiler replaces the assert line with: assert( dynamic_cast<Target>(x) == static_cast<Target>(x) );
Could you give a specific complete example (a file that would compile, with all the declarations) of how one would use what you're proposing to help make this clearer?
I enclosed two files to this reply. Don't scream about chosen class names and stuff in the example ;)

Thank you Sam, I feel quite shitty to not have known this before. I posted this because I thought static_cast couldn't "downcast" and because of downcast/upcast impairment. When I realized I could down_cast using reinterpret_cast and static_cast I should have reconsidered this instead of posting this thing. I learned C++ with visual: c:\dev\test\test.cpp(49) : error C2440: 'initializing' : cannot convert from 'class B *' to 'class C *' Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast If only the redactor could have added static_cast will do sometimes ;) Jean.

Not at all. My guidelines for these things are (though I'm sure someone can pick holes?): class B {}; class D : public B{}; B* pB; D* pD; - pD will upcast to pB implicity. - to cast from a pB to pD when I am absolutely sure that *pB is a *pD + use boost::polymorphic_downcast, if I have RTTI in this application (I don't always have it available to me) + use static_cast if I don't have RTTI - if I'm not absolutely sure that *pB is a *pD, then I use either : + dynamic_cast (if I want a null return value in case of failure) or + boost::polymorphic_cast (if I want an exception in case of failure) - avoid casts wherever possible, prefer virtual functions to produce object dependent behaviour - use reinterpret_cast rarely, as a general rule I only use this when dealing with a library that I have no control over, - if I need to cross cast, rethink the whole design, do I really need to? one final thing it that the above example won't actually work because dynamic_cast requires a polymorphic source type, ie a class with at least one virtual function, but I left out all functions for brevity. See Bjarne 15.4. sam.
-----Original Message----- From: news [mailto:news@main.gmane.org]On Behalf Of Jean Llorca Sent: 27 June 2002 16:45 To: boost-users@yahoogroups.com Subject: [Boost-Users] Re: Re: boost::polymorphic_upcast suggestion
Thank you Sam,
I feel quite shitty to not have known this before.
I posted this because I thought static_cast couldn't "downcast" and because of downcast/upcast impairment. When I realized I could down_cast using reinterpret_cast and static_cast I should have reconsidered this instead of posting this thing.
I learned C++ with visual: c:\dev\test\test.cpp(49) : error C2440: 'initializing' : cannot convert from 'class B *' to 'class C *' Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
If only the redactor could have added static_cast will do sometimes ;)
Jean.

"Jean Llorca" <yg-boost-users@m.gmane.org> wrote in message news:affbst$g9e$1@main.gmane.org...
I learned C++ with visual: c:\dev\test\test.cpp(49) : error C2440: 'initializing' : cannot convert
from
'class B *' to 'class C *' Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
If only the redactor could have added static_cast will do sometimes ;)
No, that's part of the point of static_cast: it never converts between unrelated types. -Dave
participants (3)
-
David Abrahams
-
Jean Llorca
-
Sam Partington