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