Search code examples
c++templatesboostshared-ptrexplicit

Can't created a boost::shared_ptr from this


Say I have the following abstract Class A. Now I'm trying to create a shared_ptr to A from inside Class A. So in A i have the following function:

class A {
    void A::setupArguments() const {
            ext::shared_ptr<A> ptr = ext::shared_ptr<A>(this);
        }
}

When compiling, it gives the error

Error   C2440   'initializing': cannot convert from 'Y *' to 'A *

when the shared_ptr function is defined as:

template<class Y>
explicit shared_ptr( Y * p ): px( p ), pn() // Y must be complete
{
   boost::detail::sp_pointer_construct( this, p, pn );
 }

I have read in another post that this has something to do with the shared_ptr function being explicit, where the the argument p must be strictly of type Y*. In this case, Y refers to Class A so by passing in "this", isnt "this" already explicit enough since its of type A*? I know the solution is to use std::enable_shared_from_this but I just want to understand why this would not work. For example, if we do the following, it would work

ext::shared_ptr<A>(new A())

But doesn't new A() return the same type as "this"?(both returns pointer to A) So why does new work but not "this"?


Solution

  • Since setupArguments is a const-qualified function, this is of type const A*. And const A* is not convertible to A* so it fails to compile.

    You would need to use shared_ptr<const A> or remove the const qualifier.

    The full error given should look like:

    error C2440: 'initializing': cannot convert from 'Y *' to 'A *'
            with
            [
                Y=const A
            ]
    note: Conversion loses qualifiers
    

    OT: be careful with constructing a shared_ptr from this, as it may lead to double deletes. Consider using boost::enable_shared_from_this