1

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?

4
  • Duplicate of stackoverflow.com/questions/411103/… Commented Jan 21, 2016 at 13:56
  • i'd like to add that B b; b.someMethod("HelloWorld"); show that you are not using polymorphism at all, only inheritance Commented Jan 21, 2016 at 13:57
  • There is no polymorphism in provided example. Commented Jan 21, 2016 at 14:17
  • Please note, that your code samples are not compilable by C++ compiler. You forgot the ; at the end of class declarations (class … {…};). Commented Jan 21, 2016 at 14:21

3 Answers 3

7

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&);
};
Sign up to request clarification or add additional context in comments.

Comments

0

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).

Comments

0

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.