как использовать boost :: any_cast (библиотека c ++) для приведения к базовым типам? - PullRequest
6 голосов
/ 27 октября 2009

Я использую boost :: any для полиморфных типов, мне нужно иметь возможность привести объект к базовому типу.

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);
}

Код основной функции выдает следующую ошибку во время выполнения:

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

Если я изменю static_cast в коде boost :: any_cast для reinterpret_cast, он, похоже, будет работать. Однако я не уверен в последствиях этого.

У вас есть идеи?

1 Ответ

9 голосов
/ 27 октября 2009

Upcasts (к указателю на базу) не требует явного приведения в C ++.

С другой стороны, boost::any_cast будет успешным только при приведении к тому же типу, который был изначально сохранен. (IIRC использует typeid для проверки того, что вы пытаетесь получить доступ к правильному типу, а сравнение typeid верно только для точных совпадений.)

Таким образом:

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

Тем не менее, неясно, почему вы должны использовать boost::any для полиморфных типов. В частности, он не является умным указателем и не удалит сохраненный объект. Более распространенным является хранение указателей на полиморфный объект в интеллектуальном указателе, например boost::shared_ptr<A>

...