In hindsight, given make_shared
, would shared_ptr
have a constructor that takes a raw pointer had it been introduced with C++11?
Are there strong arguments or use cases in favor of this constructor?
It would have avoided the well documented pitfall of exception-safety and the memory allocation/performance advantage of using make_shared
.
I believe another advantage of requiring shared_ptr
construction via make_shared
would be that it could be a single pointer under the hood, lowering its memory use and making things like atomic_compare_exchange a lot simpler (and possibly more efficient). (see presentation from C++Now)
I understand that a shared_ptr that basically is an intrusive_ptr (with the object and the control block coalesced) would lack features the current std::shared_ptr has. Like:
the ability to free the object separately from the control block (which is nice if you have long lived weak_ptrs)
compatibility with libraries that hand you raw pointers and the responsibility to free them
the ability to hold arbitrary resources with custom deleters (or no deleter, for non-owning pointers)
the ability to point to a sub-object (e.g., a member) while keeping the parent object alive.
What I'm suggesting is that these features may not be used commonly enough (or in the case of using it as a RAII-wrapper) may not be the best fit, to warrant the extra cost:
- a separate pointer to the control block
- (potentially) more complex atomic_compare_exchange logic, may not be worth it.
In a C++98 world (where shared_ptr was introduced) make_shared is less practical and less user friendly (the lack of perfect forwarding requires reference wrappers and the lack of variadic templates makes the implementation clunky).
make_shared
was introduced in C++11. – Bascio