Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make shared_ptr wrapper class work with make_shared

This question extends Customising std::shared_ptr or boost::shared_ptr to throw an exception on NULL dereference.

I want a class that behaves like shared_ptr, but that throws an exception when dereferencing a nullptr. In above's question, it was recommended to create a wrapper class that contains a shared_ptr, and to have that wrapper throw the exception.

However, I'd also like to continue using make_shared. Is there some way to make make_shared work with my (or any) wrapper class of shared_ptr? Something that works along the lines of

checked_shared_ptr<MyClass> csp = make_checked_shared<MyClass>(...);
like image 654
Eph Avatar asked Oct 29 '25 20:10

Eph


1 Answers

Add a suitable constructor

The easiest solution would be to add a constructor to template<class T> class checked_shared_ptr so that it can be initialized with a std::shared_ptr<T>, this would effectively make the below compile (and do what is expected).

checked_shared_ptr<MyClass> csp = std::make_shared<MyClass> (...);

Sample Implementation

template<class T>
struct checked_shared_ptr {

  template<
    class U,
    class = decltype (std::shared_ptr<T> (std::shared_ptr<U> {}))
  > checked_shared_ptr (std::shared_ptr<U> const& src)
    : _sptr (src)
  { }

  // ...

  T& operator* () {
    if (_sptr)
      return *_sptr;

    throw std::runtime_error ("nullptr");
  }

  // ...

  std::shared_ptr<T> _sptr;
};

checked_shared_ptr<MyClass> csp = std::make_shared<MyClass> ();

Note

The usage of decltype(std::shared_ptr<T> (std::shared_ptr<U>)) is so that the constructor only takes part in overload resolution if one can convert U* to T*.

  • cppreference.com - shared_ptr constructors
like image 184
Filip Roséen - refp Avatar answered Oct 31 '25 12:10

Filip Roséen - refp



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!