Search code examples
c++boostpolymorphismscoped-ptr

C++ polymorphism with boost scoped_ptr


Why does the following code not allow foo(ptr) to be called ?

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

The corresponding form where we pass references works as expected. Are we supposed not to do polymorphism with boost scoped_ptr ?

g++ with boost 1.49 gives me:

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

Solution

  • That's because foo, for some reason, takes a scoped pointer by reference. That is completely unnecessary and is the reason why the call fails. There is a conversion from scoped_ptr<B> to scoped_ptr<A> but not from scoped_ptr<B>& to scoped_ptr<A>&.

    You should pass it as reference to const.

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

    Incidentally, this isn't a "problem" of smart pointers per se. The following code fails for the same reasons as yours.

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

    In order to fix this you have to pass the pointer either by value, or, if you're sufficiently perverted, by reference to const

     void foo (A * const & p); // <-- a perv wrote this