The code I'm working with has its own smart pointer implementation which does simple reference counting. Yes, we shouldn't have our own implementation. Yes, we should be using one from boost or some such. Bear with me.
I found I wanted to write code like this:
...
CountedPointer<Base> base;
...
CountedPointer<Derived> derived;
...
base = derived;
However, the copy constructor for CountedPointer has a prototype like this:
CountedPointer(const CountedPointer<T> &other);
So the above code won't compile since it can't find a suitable constructor (or assignment operator - it's the same story there). I tried re-writing the copy constructor with a prototype like this:
template<U>
CountedPointer(const CountedPointer<U> &other);
However, I hit the problem that the copy constructor must access a private member of the object it's copying (i.e. the raw pointer) and if it's in a different specialisation of CountedPointer, they're not visible.
Alexandrescu avoids this problem in his library Loki by having accessor functions for the encapsulated pointer, but I'd prefer not to give direct access to the raw pointer if possible.
Is there any way I can write this to allow the derived to base copy, but not allow general access to the raw pointer?
Update: I've implemented the accepted answer below, and it works well. I spent a while figuring out why my program seg-faulted horribly when I only provided the templated version of the copy constructor, replacing the original un-templated version. Eventually, I realised that the compiler doesn't regard the templated version as being a copy constructor, and provides a default one. The default one just dumbly copies the contents without updating the counter, so I end up with dangling pointers and double frees. The same sort of thing applies to the assignment operator.