Why do shared_ptr deleters have to be CopyConstructible?

This question was perplexing enough that I emailed Peter Dimov (implementer of boost::shared_ptr and involved in standardization of std::shared_ptr)

Here’s the gist of what he said (reprinted with his permission):

My guess is that the Deleter had to be CopyConstructible really only as a
relic of C++03 where move semantics didn’t exist.

Your guess is correct. When shared_ptr was specified rvalue references
didn’t exist yet. Nowadays we should be able to get by with requiring
nothrow move-constructible.

There is one subtlety in that when

pi_ = new sp_counted_impl_pd<P, D>(p, d);

throws, d must be left intact for the cleanup d(p) to work, but I
think that this would not be a problem (although I haven’t actually
tried to make the implementation move-friendly).
[…]
I think that there will be no problem for the
implementation to define it so that when the new throws, d will be left
in its original state.

If we go further and allow D to have a throwing move constructor, things get
more complicated. But we won’t. 🙂

Leave a Comment

Hata!: SQLSTATE[HY000] [1045] Access denied for user 'divattrend_liink'@'localhost' (using password: YES)