I've been working a lot with C++ in my new job. This means getting to grips once more with the STL, generic programming and templates. The more I dig into templates the more Alice In Wonderland it gets. We were playing around with a reference counting smart pointer. The basic template was ::
template <class ReferencePtr> class AutoPtr {
...
}
where ReferencePtr is the class of the pointer we wish to hold manage. For example
Foo * foo = new Foo;
AutoPtr<Foo> ptr = foo;
That was all well and good until we tried
const Foo * foo = new Foo;
AutoPtr<const Foo> ptr = foo;
This failed to compile. When we investigated we found parts of AutoPtr had declarations such as one of the constructors.
AutoPtr(const ReferencePtr * ref);
The problem with this is that if ReferencePtr is expanded as "const Foo" then the constructor expands to.
AutoPtr(const const Foo * ref);
which results in a compilation error. How to fix this? We need a const stripping template class to get to the raw type Foo without it's const. Here is a version
template <C> struct ConstStripper {
typedef C type_name;
};
template <C> struct ConstStripper<const C> {
typedef C type_name;
};
now we redefine our constructor as
AutoPtr(const typename ConstStripper<ReferencePtr>::type_name * ref);
now whether ReferencePtr is
const Foo or just
Foo const ConstStripper<ReferencePtr>::type_name will always expand to just Foo. Neat!
Now isn't that a
constipated solution.