I am trying to overload some template function to perform specific action if I call it using a given class MyClass or any derived class MyClassDer. Here is the code:
#include <iostream>
struct MyClass {
virtual void debug () const {
std::cerr << "MyClass" << std::endl;
};
};
struct MyClassDer : public MyClass {
virtual void debug () const {
std::cerr << "MyClassDer" << std::endl;
};
};
template <typename T> void func (const T& t) {
std::cerr << "func template" << std::endl;
}
void func (const MyClass& myClass) {
std::cerr << "func overloaded" << std::endl;
myClass.debug ();
}
int main(int argc, char **argv) {
func (1);
MyClass myClass;
func (myClass);
MyClassDer myClassDer;
func (myClassDer);
}
The output is:
func template
func overloaded
MyClass
func template
func (myClassDer)
calls the template function instead of void func (const MyClass& myClass)
. What can I do to get the expected behavior?
Thanks
You can use SFINAE:
#include <type_traits>
template <typename T>
void func (const T& t, typename std::enable_if<!std::is_base_of<MyClass, T>::value>::type * = nullptr) {
std::cout << "func template" << std::endl;
}
template <
typename T
, typename = typename std::enable_if<std::is_base_of<MyClass, T>::value>::type
>
void func (const T& t) {
std::cout << "func overloaded" << std::endl;
t.debug ();
}
If you don't have C++11, boost provides the same functionality.
EDIT
This should work without C++11 (using boost):
#include "boost/type_traits.hpp"
template <typename T>
void func (const T& t, typename boost::enable_if<!boost::is_base_of<MyClass, T>::value>::type * = 0) {
std::cout << "func template" << std::endl;
}
template <typename T>
void func (const T& t, typename boost::enable_if<boost::is_base_of<MyClass, T>::value>::type * = 0) {
std::cout << "func overloaded" << std::endl;
t.debug ();
}