Search code examples
c++c++11smart-pointersstatic-castweak-ptr

Function overloading resolution with weak_ptr as argument


I have:

class A : public std::enable_shared_from_this<A>
{...};

class B : public A
{...}; 

void doCoolStuff(std::weak_ptr<A> obj)
{...}

void doCoolStuff(std::weak_ptr<B> obj)
{
 ...
 doCoolStuff(std::static_pointer_cast<A>(obj.lock())); (1)
}

And then in B function:

void B::doReallyCoolStuff()
{
 doCoolStuff(std::static_pointer_cast<B>(shared_from_this())); (2)
}

So problems are:

  1. Compiler error: error C2440: 'static_cast' : cannot convert from 'B *const ' to 'A *'
  2. Compiler error: error C2668: ambiguous call to overloaded function

I don't understand how to resolve either of them, because:

  1. I think it's somehow connected with shared_from_this, because this is const pointer. But I don't know how to handle this situation without const_cast.
  2. I don't know if functions can be overloaded by different types of weak pointers.

Build environment: MSVS 2013 express

Please, help. Thank you


Solution

  • As for problem (2), you can of course overload like this. But the problem is that you're calling the function with the type std::shared_ptr<B>. This requires an implicit conversion to a std::weak_ptr, and it can convert to both std::weak_ptr<A> and std::weak_ptr<B>. Both of these are implemented by an implicit conversion constructor inside std::weak_ptr, which means none of them is better than the other. Hence the ambiguity.

    To solve this, you can specify the type explicitly:

    void B::doReallyCoolStuff()
    {
        doCoolStuff(std::weak_ptr<B>(std::static_pointer_cast<B>(shared_from_this())));
    }
    

    Live example

    Alternatively, you can provide overloads of doCoolStuff taking std::shared_ptr.

    As the live example above shows, I wasn't able to reproduce issue (1).