Search code examples
c++templatestemplate-specialization

c++ template specialization for all subclasses


I need to create a template function like this:

template<typename T>
void foo(T a)
{
   if (T is a subclass of class Bar)
      do this
   else
      do something else
}

I can also imagine doing it using template specialization ... but I have never seen a template specialization for all subclasses of a superclass. I don't want to repeat specialization code for each subclass


Solution

  • You can do what you want but not how you are trying to do it! You can use std::enable_if together with std::is_base_of:

    #include <iostream>
    #include <utility>
    #include <type_traits>
    
    struct Bar { virtual ~Bar() {} };
    struct Foo: Bar {};
    struct Faz {};
    
    template <typename T>
    typename std::enable_if<std::is_base_of<Bar, T>::value>::type
    foo(char const* type, T) {
        std::cout << type << " is derived from Bar\n";
    }
    template <typename T>
    typename std::enable_if<!std::is_base_of<Bar, T>::value>::type
    foo(char const* type, T) {
        std::cout << type << " is NOT derived from Bar\n";
    }
    
    int main()
    {
        foo("Foo", Foo());
        foo("Faz", Faz());
    }
    

    Since this stuff gets more wide-spread, people have discussed having some sort of static if but so far it hasn't come into existance.

    Both std::enable_if and std::is_base_of (declared in <type_traits>) are new in C++2011. If you need to compile with a C++2003 compiler you can either use their implementation from Boost (you need to change the namespace to boost and include "boost/utility.hpp" and "boost/enable_if.hpp" instead of the respective standard headers). Alternatively, if you can't use Boost, both of these class template can be implemented quite easily.