std::default_delete can be specialized to allow std::unique_ptrs to painlessly manage types which have to be destroyed by calling some custom destroy-function instead of using delete p;.
There are basically two ways to make sure an object is managed by a std::shared_ptr in C++:
Create it managed by a shared-pointer, using
std::make_sharedorstd::allocate_shared. This is the preferred way, as it coalesces both memory-blocks needed (payload and reference-counts) into one. Though iff there are onlystd::weak_ptrs left, the need for the reference-counts will by necessity still pin down the memory for the payload too.Assign management to a shared-pointer afterwards, using a constructor or
.reset().
The second case, when not providing a custom deleter is interesting:
Specifically, it is defined to use its own deleter of unspecified type which uses delete [] p; or delete p; respectively, depending on the std::shared_ptr being instantiated for an Array or not.
Quote from n4659 (~C++17):
template<class Y> explicit shared_ptr(Y* p);4 Requires:
Yshall be a complete type. The expressiondelete[] p, whenTis an array type, ordelete p, whenTis not an array type, shall have well-defined behavior, and shall not throw exceptions.
5 Effects: WhenTis not an Array type, constructs ashared_ptrobject that owns the pointerp. Otherwise, constructs ashared_ptrthat ownspand a deleter of an unspecified type that callsdelete[] p. WhenTis not an array type, enablesshared_from_thiswithp. If an exception is thrown,delete pis called whenTis not an array type,delete[] potherwise.
6 Postconditions:use_count() == 1 && get() == p.
[…]template<class Y> void reset(Y* p);3 Effects: Equivalent to
shared_ptr(p).swap(*this).
My questions are:
- Is there a, preferably good, reason that it is not specified to use
std::default_deleteinstead? - Would any valid (and potentially useful?) code be broken by that change?
- Is there already a proposal to do so?