I've been teaching myself the smart pointers that are part of C++0x and came across something that feels inconsistent to me. Specifically, how the destruction policy of unique_ptr<> and shared_ptr<> are handled.

For unique_ptr<>, you can specialize std::default_delete<> and from then on unless you explicitly request a different destruction policy, the new default will be used.

Consider the following:

struct some_c_type;

some_c_type *construct_some_c_type();
void destruct_some_c_type(some_c_type *);

namespace std  {
    template <> struct default_delete<some_c_type> {
        void operator()(some_c_type *ptr) {
            destruct_some_c_type(ptr);
        }
     };
}

Now, once that's in place, unique_ptr<> will use the appropriate destruction policy by default:

// Because of the specialization, this will use destruct_some_c_type
std::unique_ptr<some_c_type> var(construct_some_c_type());

Now compare this to shared_ptr<>. With shared_ptr<>, you need to explicitly request the appropriate destruction policy or it defaults to using operator delete:

// error, will use operator delete 
std::shared_ptr<some_c_type> var(construct_some_c_type());

// correct, must explicitly request the destruction policy
std::shared_ptr<some_c_type> var(construct_some_c_type(),
                                 std::default_delete<some_c_type>());

Two questions.

  1. Am I correct that shared_ptr<> requires the destruction policy to be specified every time it's used or am I missing something?
  2. If I'm not missing something, any idea why the two are different?

P.S. The reason I care about this is my company does a lot of mixed C and C++ programming. The C++ code often needs to use C-style objects so the ease of specifying a different default destruction policy is quite important t

Edit
Report