Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I use shared_from_this in a derived class without superfluous RC manipulations?

If I want to create a shared_ptr<Derived> in a derived class member function in a hierarchy that inherits from a base class, I can use shared_from_this and static_pointer_cast:

class Base: public std::enable_shared_from_this<Base> {
};

class Der: public Base {
public:
  std::shared_ptr<Der> make_SP_to_Me () 
  { return std::static_pointer_cast<Der>(shared_from_this()); }
};

My concern is that static_pointer_cast accepts its argument by lvalue-ref-to-const, so when the new shared_ptr<Der> is created, the reference count in the control block is incremented. When the shared_ptr<Base> returned from shared_from_this is destroyed, the refcount in the control block will be decremented again. I was suprised to see that there is no static_pointer_cast overload taking an rvalue that would avoid the need to manipulate the refcount in the control block.

shared_ptr<T> has a templatized constructor taking rvalues of type shared_ptr<U> that performs moves, thus avoiding the need to do refcount manipulations. Is there some reason that static_pointer_cast doesn't do the same thing? And is there some way for me to write the code above that doesn't involve unnecessary refcount manipulations?

like image 717
KnowItAllWannabe Avatar asked Dec 10 '14 21:12

KnowItAllWannabe


1 Answers

It looks like you're going to have to rely on return-value optimisation and hope that it is smart enough to help you out.

If std::*_pointer_cast had overloads accepting forwarding references (T&&) then they could transfer ownership from temporaries and this would not be a problem. I consider it an oversight in the library since C++11.

like image 200
Lightness Races in Orbit Avatar answered Nov 06 '22 18:11

Lightness Races in Orbit