For example, instead of
void shared_ptr::reset() noexcept;
template
void shared_ptr::reset(Y* ptr);
one may think of
While the design choices of the other answers are all valid, they do assume one thing that does not fully apply here: Semantic equivalence!
void shared_ptr::reset() noexcept;
// ^^^^^^^^
template
void shared_ptr::reset(Y* ptr);
The first overload is noexcept
, while the second overload isn't. There is no way to decide the noexcept
-ness based on the runtime value of the argument, so the different overloads are needed.
Some background information about the reason for the different noexcept
specifications: reset()
does not throw since it is assumed that the destructor of the previously contained object does not throw. But the second overload might additionally need to allocate a new control block for the shared pointer state, which will throw std::bad_alloc
if the allocation fails. (And reset
ting to a nullptr
can be done without allocating a control block.)