I have a base class MessageBase
, from which I derive various other message classes, e.g., MessageDerived
. I have another class that does some processing on various types of data, including a catchall method template:
struct Process {
void f(int a);
void f(const char* b);
template<typename T> void f(const T &t) { ... }
};
So if I call Process::f
on a message object, the template method is called.
Now I want to add custom functionality for for my message classes. I am not allowed to change Process
, so I want to derive from it (but even if I could change it, I can't find a way to get the custom functionality). I tried:
struct ProcessDerived : public Process {
void f(const MesaageBase& m) { ... } // Custom functionality for messages.
};
But that only works when I call ProcessDerived::f
on a MessageBase
object. If I invoke it on a MessageDerived
object, the template method gets selected instead.
Is there a way to get the custom function selected on all message classes while letting the template catch all other types?
You need to use SFINAE here. Here is an example (note that it needs c++11 to work):
struct ProcessDerived : public Process
{
template<typename T> void f(const T &t, typename std::conditional<std::is_base_of<MessageBase, T>::value, int, void>::type = 0)
{
/// do something specific
}
template<typename T> void f(const T &t, ...)
{
return Process::f (t);
}
};
};
You can read more about it at http://en.wikipedia.org/wiki/Substitution_failure_is_not_an_error