how to use boost::any_cast to cast to base types?

Michel picture Michel · Oct 27, 2009 · Viewed 13.6k times · Source

I am using boost::any to have polymorphic types, I need to be able to cast an object to its base type.

class A {
    public:
        int x;
        virtual int foo()= 0;
};

class B : public A {
    public:
        int foo() {
            return x + 1;
        }
};


int main() {
    B* bb = new B();
    boost::any any = bb;
    bb->x = 44;
    A* aa = boost::any_cast<A*>(any);
}

The code of the main function throws the following error at runtime:

terminate called after throwing an instance of 'boost::exception_detail::clone_impl<boost::exception_detail::error_info_injector<boost::bad_any_cast> >'
  what():  boost::bad_any_cast: failed conversion using boost::any_cast
Abort trap

If I change the static_cast in the boost::any_cast code for reinterpret_cast it seems to work. However I am not sure about the consequences of that.

Do you have any ideas?

Answer

UncleBens picture UncleBens · Oct 27, 2009

Upcasts (towards pointer-to-base) don't require an explicit cast in C++.

On the other hand, boost::any_cast will only succeed when casting to the exact same type as was originally stored. (IIRC it uses typeid to check that you are trying to access the correct type, and typeid comparisons are only true for exact matches.)

Hence:

A* aa = boost::any_cast<B*>(any);

However, it is somewhat unclear why you should be using boost::any for polymorphic types. In particular, it is not a smart pointer and will not delete the pointed-at object. More common is to store pointers to polymorphic object in a smart pointer, e.g boost::shared_ptr<A>