I am new to C++ and trying to write a interface as below:
template <class T>
class Comparable
{
protected:
Comparable(){};
public:
virtual int compare(const T&&)=0;
int compare(const T& o)
{
return this->compare(std::move(o));
}
};
I did this to try to get the compare method to work with both l/r values. I derived the following class from Comparable:
class Monkey : Comparable<Monkey>
{
private:
char name[512];
public:
Monkey(const char*&& name)
{
strcpy(this->name, name);
}
const char *getName() { return name; }
int compare(const Monkey&& m)
{
return strcmp(name, m.name);
}
};
with the main() method as follows:
Monkey m1(argv[1]), m2(argv[2]);
printf("\"%s\" \"%s\" %d\n", m1.getName(), m2.getName(), m2.compare(m1));
But i get a compilation error:
cannot bind 'Tests::Monkey' lvalue to 'const Tests::Monkey&&' initializing argument 1 of 'virtual int Tests::Monkey::compare(const Tests::Monkey&&)' Build Failed
Why is the method call not binding to the compare method in the base class?
When i create them both as virtual in the base class and write them both in the derived class, the binding works fine, but it doesn't work and i get a compile error if I try to compile it as it's written here.
This is name hiding; name in the derived class hides name in the base class. In short, you can't overload functions through different scopes.
According to the rule of unqualified name lookup, for m2.compare(m1)
, m2
is of type Monkey
, the name compare
will be found at the scope of the derived class Monkey
firstly, then name lookup stops. The compare
s in the base class won't be considered for the following overload resolution at all.
(emphasis mine)
For an unqualified name, that is a name that does not appear to the right of a scope resolution operator ::, name lookup examines the scopes as described below, until it finds at least one declaration of any kind, at which time the lookup stops and no further scopes are examined.
You can introduce the names of base class into the scope of the derived class by using
:
class Monkey : Comparable<Monkey>
{
...
using Comparable<Monkey>::compare;
int compare(const Monkey&& m)
{
return strcmp(name, m.name);
}
};