Can I call an unspecialized template method from a specialized one?
This is easy when using inheritance:
class SomeBaseClass {
virtual void DoWork() { /* Do something */ }
};
class SomeClass : public SomeBaseClass {
void DoWork() {
// Do something first
SomeBaseClass::DoWork();
}
};
But is a bit different when using templates:
template <class T>
class SomeClass {
void DoWork();
};
template<class T>
void SomeClass<T>::DoWork() { /* Do something */}
template<>
void SomeClass<int>::DoWork() {
// Do something first
DoWork<>(); // Call method from line 8
}
My generic DoWork function has a lot of really good code in it that I'd hate to duplicate. My specialized one just has an extra step that it needs to perform when a specific type is used.
You're thinking about this the wrong way. The solution is not to have your class specialized, but to have your function specialized. What I mean here is to use tag dispatch
That is, declare two
private
helper functions in your class namedDoWorkHelper
, one of which is overloaded for the specialized type, and the other not.The way we do this is to wrap our type in a 'tag' that is basically an empty struct, and then specialize the tag for our type of interest:
true_type
andfalse_type
are essentially wrappers for booleantrue
andfalse
. They're nice because they're types and not values (and when we template we care all about types)Next, we'll declare our class with aforementioned overloads:
The idea here is that
true_type
means "Yes, this function is for the specialized version!"Here's what the definitions look like:
That's it. The specialized version will do its thing, and then call the unspecialized version, and the unspecialized version (for all other
T
), will simply do its thing.Here's a live demo that demonstrates tag dispatch in action