Search code examples
c++templatesoverload-resolution

C++: "specializing" a member function template to work for derived classes from a certain base class


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?


Solution

  • 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