Using function overloads in the accepted answer to replace function template specialization isn't always a good idea. For the example code in the question, function overloading cannot provide a default implementation which prints "Unknown" for non-specialized classes. Other examples where function overloading is insufficient include tuples and virtually any variadic programming.
The primary reason why the code in question doesn't work is that currently, type deduction and conversion do not play nicely with each other. You need to cast &b
to a pointer type to its parent class (i.e. IBase*) which the specialized function expects. Because of this issue in current C++, it's necessary to help out the compiler by using.
get_func((const IBase*)&b);
secondly, it may be better to add virtual
to
std::string func() const { return "From MyClass"; }
,since IBase::func is defined as a virtual member function. (This isn't necessary for all compilers: C++ "virtual" keyword for functions in derived classes. Is it necessary?).
With these changes, code below outputs what's expected:
Unknown
From MyClass
Code:
#include <string>
#include <iostream>
using namespace std;
class IBase
{
public:
virtual std::string func() const = 0;
};
class MyClass : public IBase
{
public:
virtual std::string func() const { return "From MyClass"; }
};
template <class T>
std::string get_func(const T* t)
{
return "Unknown";
}
template <>
std::string get_func<IBase>(const IBase* t)
{
return t->func();
}
int main()
{
int a;
MyClass b;
cout << get_func(&a) << endl; // <- Returns 'Unknown'. Good.
cout << get_func((const IBase*)&b) << endl; //
}