I was thinking about using CRTP classes to help with overloading and wondered what the following bit of code would do:
#include <iostream>
#include <typeinfo>
template <class TDerived>
class FunctionImplementation
{
};
class AbstractFunction
{
};
class BaseFunction : public AbstractFunction, public FunctionImplementation<BaseFunction>
{
};
class DerivedFunction : public BaseFunction, public FunctionImplementation<DerivedFunction>
{
};
template <class TDerived>
void foo(const FunctionImplementation<TDerived>& function) {
std::cout << "In foo for " << typeid(TDerived).name() << std::endl;
}
int main() {
BaseFunction base;
DerivedFunction derived;
foo(base);
foo(derived);
}
With GCC 4.2 on OS X it doesn't compile:
overload.cpp: In function ‘int main()’:
overload.cpp:31: error: no matching function for call to ‘foo(DerivedFunction&)’
With Clang 4.0 on the same system, it compiles and does the 'natural' thing when it runs:
In foo for 12BaseFunction
In foo for 15DerivedFunction
With Visual C++ 2010, it also compiles but runs differently:
In foo for class BaseFunction
In foo for class BaseFunction
Finally, GCC 4.7.2 on Linux does not compile but gives a more complete and fairly authoritative-sounding error message:
overload.cpp: In function ‘int main()’:
overload.cpp:31:16: error: no matching function for call to ‘foo(DerivedFunction&)’
overload.cpp:31:16: note: candidate is:
overload.cpp:22:6: note: template<class TDerived> void foo(const FunctionImplementation<TDerived>&)
overload.cpp:22:6: note: template argument deduction/substitution failed:
overload.cpp:31:16: note: ‘DerivedFunction’ is an ambiguous base class of ‘const FunctionImplementation<TDerived>’
Which is correct? I am no expert at navigating the language standard...