The simple answer is to change the name of the getName
method in either A
or B
.
If you really don't want to do that, then don't say I didn't warn you. Your alternative is to override getName(int)
in A
and simply call its namesake in B
:
template< typename T >
class A : public T
{
public:
string getName() { return name; }
string getName(int index) { return T::getName(index); }
This should compile even if T
doesn't have a getName
method, because the compiler will not attempt to instantiate A::getName(int)
unless you actually call it.
If you're interested to see how far you could go with this, the following is a version which will make A::getName(int)
callable even if T
doesn't have a getName
method. In this case, it will return the empty string. (I don't recommend actually using this.)
template< typename T, typename F >
class has_getName
{
struct yes { char x; };
struct no { yes y, z; };
template <typename U> static no test(...);
template <typename U> static yes test(std::integral_constant<F, &U::getName>*);
public:
typedef std::integral_constant<bool, sizeof(test<T>(0)) == sizeof(yes)> type;
};
template< typename T >
class A : public T
{
string getNameHelper(int index, std::false_type) { return string(); }
string getNameHelper(int index, std::true_type) { return T::getName(index); }
public:
string getName() { return name; }
string getName(int index) {
return getNameHelper(index, typename has_getName<T, string(T::*)(int)>::type());
}
N.B. All your getName
methods should really be const
as they do not modify the object.