Quote Originally Posted by Codeplug
>> Also, perhaps the ZeroRef function itself would go well as a template parameter
Excellent idea [everyone]. I shy'd away from it at first since it changes the type of the smart pointer type. But on second thought, I like that since you wouldn't want to assign two smart pointers with different ZeroRef functors. Plus, it's more inline with the std:: way of doing it.
Why not? Just assign the deleter along with the pointer. Since the old pointer either gets deleted or released to the care of other smart pointers, you don't need the old deleter anymore. So you can just take a copy of the new one. (That's why Boost's shared_ptr stores the deleter in the same struct as the share count, btw.)

>> I'd use a Boost.Function object to store the deleter.
This seems like overkill to me since the fuctor's signature will always return void and take a pointer to T. If you need a different signature to be called, then using an adapter class is the more std:: way. This is also how boost::shared_ptr handles it.
Boost.Function isn't about different signatures (it's templated on the signature), but about different callable objects, such as function pointers, functors, ...
The advantage would be that you could assign both of these as deleters:
Code:
template<typename T>
void my_del_function(T *& p) {
  delete p;
  p = 0;
}
Code:
template<typename T>
struct my_del_functor
{
  void operator()(T *& p) {
    delete p;
    p = 0;
  }
};
For getting both of these, you either have to template the smart pointer on the deleter type (as I explained above, I don't think that makes much sense) or use something akin to Boost.Function.