In C++11 std::shared_ptr
has four constructors which can be passed deleter objects d
of type D
. The signatures of these constructors are t
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);
throws,
d
must be left intact for the cleanupd(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 thenew
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. :-)