
On Jul 16, 2008, at 4:51 PM, Mathias Gaunard wrote:
"I personally don't see the point in dynamic deleters, they're only specializations of static ones."
The advantage is that instead of doing this: struct B; class A { public: typedef std::unique_ptr<B, void(*)(B*)> handle; private: handle p_; public: static void reclaim(B*); // used as the deleter A(); // p_ constructed with reclaim handle get() {return std::move(p_);} }; int main() { A a; A::handle p = a.get(); // ... } // call A::reclaim(p.get()) one could do this: struct B; class A { shared_ptr<B> p_; public: static void reclaim(B*); // used as the deleter A(); // p_ constructed with reclaim shared_ptr<B> get() {return p_;} }; int main() { A a; shared_ptr<B> p = a.get(); // ... } // call A::reclaim(p.get()) The difference is that you don't have to use A::handle to mask your smart pointer type. You can advertise that shared_ptr<B> will be your smart pointer type. When you do so, you still leave yourself the freedom to change your destruction policy in the future without disturbing API or ABI. However recall that in the first case you can change your destruction policy by simply rewriting A::reclaim(B*) without disturbing API or ABI as well. The difference here is subtle, and some may even say insignificant. Others will say very significant. If the client of A also has a client C that uses the smart_ptr of A then the closer you can come to a "common well known type" the better. shared_ptr<B> is better known than unique_ptr<B, void(*)(B*)> or A::handle. It is good to have all of these tools in the toolbox: shared_ptr, unique_ptr, scoped_ptr. There are different situations where each one is best. Disclaimer: I currently don't have a good use case for scoped_ptr. But people I highly respect say they do and that's good enough for me. Note: I believe the more important difference between shared_ptr and unique_ptr is the copy vs move characteristic as opposed to the static vs dynamic deleter characteristic. shared_ptr is better suited to handle dynamic deleters because it is already committed to auxiliary heap storage to store the reference count and so can handle the dynamic deleter with nearly zero extra overhead. The same isn't true of unique_ptr. One should generally choose between shared_ptr and unique_ptr based on whether you want copy or shared-ownership semantics vs unique-ownership/move-only semantics. Neither of these choices is universally better than the other (despite the design of some other languages ;-) ). -Howard