Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

like image 353
DoctorMoisha Avatar asked Feb 12 '23 00:02

DoctorMoisha


1 Answers

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).

like image 59
Angew is no longer proud of SO Avatar answered Feb 16 '23 03:02

Angew is no longer proud of SO