Mixing template function overloading and inheritance

c++, inheritance, templates

Solution

Two ways using `type_traits` to test if the argument is derived from Interface.

#include <boost/type_traits.hpp>

class Interface {};
class Impl: public Interface {};

class Bar
{
    template <class T> void foo_impl(T& value, boost::false_type)
    {
        std::cout << "generic\n";
    }
    void foo_impl(Interface& value, boost::true_type)
    {
        std::cout << "Interface\n";
    }
public:
    template<typename T> void foo(T& t) {
        foo_impl(t, boost::is_base_of<Interface, T>());
    }

};

Or disable the template if the condition is met, leaving only the non-template as a candidate.

#include <boost/utility/enable_if.hpp>
#include <boost/type_traits.hpp>

class Interface {};
class Impl: public Interface {};

class Bar
{
public:
    template<typename T>
    typename boost::disable_if<boost::is_base_of<Interface, T>, void>::type foo(T& t)
    {
        std::cout << "generic\n";
    }

    void foo(Interface&)
    {
        std::cout << "Interface\n";
    }
};

Problem

The following code prints: ``` generic overload ``` But what I wanted is that the overload or the specialization were called in both cases, not the generic one. I'm not trying to mix overloading with template specialization, they're here together because none worked as I expected. Is there any template magic to accomplish this? ``` #include <iostream> class Interface {}; class Impl: public Interface {}; class Bar { public: template<typename T> void foo(T& t) { std::cout << "generic\n"; } void foo(Interface& t) { std::cout << "overload\n"; } }; template<> void Bar::foo<Interface>(Interface& t) { std::cout << "specialization\n"; } int main() { Bar bar; Impl impl; Interface& interface = impl; bar.foo(impl); bar.foo(interface); return 0; } ```

Original source

Related problems