Reputation: 31
I have two classes:
template<typename T>
class A{
public:
T& someMethod(std::string);
}
template<typename T>
class B: public A<T>{
public:
T& someMethod(T&,T&);
}
My problem is that know I can't call
B b;
b.someMethod("HelloWorld");
because my compiler can't see someMethod(std::string)
. Do you know why it is so?
Upvotes: 1
Views: 80
Reputation: 310920
The problem is that a method in a derived class hides all methods of the base class with the same name.
To call the base class method you have to use a qualified name.
For example
#include <iostream>
#include <string>
template<typename T>
class A{
public:
T& someMethod( std::string s )
{
static T t;
std::cout << "A::someMethod: " << s << std::endl;
return ++t;
}
};
template<typename T>
class B: public A<T>{
public:
T& someMethod(T& t1,T& t2 )
{
static T t;
std::cout << "B::someMethod" << std::endl;
return t = t1 + t2;
}
};
int main()
{
B<int> b1;
b1.A::someMethod( "Hi" );
// ^^^^^^^^^^^^^^
}
The program output is
A::someMethod: Hi
Otherwise you can include the declaration of the base class method in the scope of a derived class by means of a using declaration.
Upvotes: 0
Reputation: 52274
Do you know why it is so?
Yes.
During a name look up in a scope, the search for definitions stop going from included to enclosing scope when a scope has definitions for the names. And class inheritance is considered as nesting scope (with some caveats irrelevant to the current discussion to handle multiple inheritance). Thus when the B definition of someMethod is found, the search stop and A is not looked in. ForEveR gave the way to import the definitions of A into B with using
.
Note that the search algorithm is a general rule and applies to other kind of nested scopes, blocks (but declaration of functions of blocks is not something done often nowadays) and namespace (try defining overloaded functions ns1::someFunction and ns2::someFunction, in ns2 you won't be able to call ns1::someFunction if you don't import its declaration).
Upvotes: 0
Reputation: 55887
Yes, it's name hiding. You should just add using declaration.
template<typename T>
class B: public A<T>{
public:
using A<T>::someMethod;
T& someMethod(T&,T&);
};
Upvotes: 7