C++ полиморфизм с бустом scoped_ptr

Почему следующий код не позволяет вызывать foo(ptr)?

#include <boost/scoped_ptr.hpp>
struct A {
    virtual ~A() {}
};

struct B: public A {};

void foo(boost::scoped_ptr<A>& a) {}

void goo(A& a) {}
int main() {
    boost::scoped_ptr<B> ptr(new B);
    foo(ptr);
    B b;
    goo(b);
}

Соответствующая форма, где мы передаем ссылки, работает как положено. Разве мы не должны делать полиморфизм с boost scoped_ptr?

g ++ с надписью 1.49 дает мне:

error: invalid initialization of reference of type ‘boost::scoped_ptr<A>&’ from expression of type ‘boost::scoped_ptr<B>’

1 ответ

Решение

Это потому что foo по какой-то причине берет указатель на область видимости по ссылке. Это совершенно не нужно и является причиной сбоя вызова. Есть преобразование из scoped_ptr<B> в scoped_ptr<A> но не из scoped_ptr<B>& в scoped_ptr<A>&,

Вы должны передать это как ссылку на const.

void foo(boost::scoped_ptr<A> const & a) {}

Кстати, это не "проблема" умных указателей как таковых. Следующий код не работает по тем же причинам, что и ваш.

void foo(A*& p) {}
int main()
{
    B* p = new B;
    foo(p); //FAIL
}

Чтобы исправить это, вы должны передать указатель либо по значению, либо, если вы достаточно извращены, по ссылке на const

 void foo (A * const & p); // <-- a perv wrote this
Другие вопросы по тегам