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
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.