Item 45: Use Member Function Templates to Accept "All Compatible Types"
Or: How to make smart pointers do type conversion like raw pointers? (Of course, the trick here doesn’t just apply to smart pointers.)
Raw pointers do type conversions just fine:
class A {};
class B: public A {};
class C: public B {};
A* p = new B;  // Convert B* to A*.
A* q = new C;  // Convert C* to A*.
const A* r = p;  // Convert A* to const A*.
To make smart pointers do these:
template<typename T>
class SmartPtr {
 public:
  // Member function template that accepts
  // all compatible types.
  template<typenaem U>
  SmartPtr(const SmartPtr<U>& other)
  : ptr(other.get()) {}
  T* get() const { return ptr; }
 private:
  T* ptr;
};
And this compiles only if U* is convertible to T*.
And the trick doesn’t stop here. The “all compatible types” could be other smart pointers, raw pointers, or const pointers.
Note: Even if you define a generalized copy constructor (which is a member template), it doesn’t mean compiler won’t generate its own copy constructor. If you want to control that behavior, you have to define a (non-templatized) copy constructor, too.
