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?

David G
  • 94,763
  • 41
  • 167
  • 253
Matimath
  • 31
  • 1
  • Duplicate of http://stackoverflow.com/questions/411103/function-with-same-name-but-different-signature-in-derived-class – Sasha Jan 21 '16 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 – Guiroux Jan 21 '16 at 13:57
  • There is no polymorphism in provided example. – SergeyA Jan 21 '16 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 … {…};`). – Sasha Jan 21 '16 at 14:21

3 Answers3

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&);
};
ForEveR
  • 55,233
  • 2
  • 119
  • 133
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).

AProgrammer
  • 51,233
  • 8
  • 91
  • 143
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.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335