c++ – shared_ptr and make_shared implementations (for learning)

Recently, I’ve been going through Scott Meyer’s Effective Modern C++ and found the discussion on shared_ptr really interesting. I also watched Louis Brandy’s Curiously Recurring C++ Bugs at Facebook talk which also had some details about how shared_ptr works, and I thought it would be fun to implement my own to see if I actually understood it.

Here is my implementation of shared_ptr and make_shared: https://godbolt.org/z/8Yec9K

Any and all review comments would be greatly appreciated. In particular, I had a few questions when comparing my implementation against the STL’s:

  • I noticed that in the STL implementation I looked at, the class and constructor are templated on different types (i.e. the constructor is implemented like: template <typename T> class shared_ptr { public: template <typename U> explicit shared_ptr(U* val); };) I was wondering why the both the class and the constructor need to be templated?
  • The following compiles: std::shared_ptr<int()> a(new int(10));, but the similar idea doesn’t compile with my implementation. How can I fix this?
  • Is there a downside to my using an std::function to store the custom deleter? I noticed that the STL implementation I looked at doesn’t do this, but the type erasure that std::function provides seem to fit in really well with how the custom deleter is supposed to work.
  • I know that std::make_shared is supposed to use only one allocation to allocate both the control block and the T object. I couldn’t figure out how to do it in an easy way though. Is there an easy way to implement that with what I have now?

I’m sure there’s a lot of other bugs and mistakes with my code, and I would greatly appreciate any and all feedback. Thanks for your time!