0

Possible Duplicate:
overloaded functions are hidden in derived class

It seems that I cannot directly use methods from a base class in a derived class if they are overloaded in both the base class and the derived class in C++. The following code produces the error no matching function for call to ‘Derived::getTwo()’.

class Base {
public:
    int getTwo() {
        return 2;
    }
    int getTwo(int, int) {
        return 2;
    }
};

class Derived : public Base {
public:
    int getValue() {
        // no matching function for call to ‘Derived::getTwo()’
        return getTwo();
    }
    int getTwo(int) {
        return 2;
    }
};

If I change return getTwo(); to return ((Base*) this)->getTwo(), it works, but that looks ugly to me. How can I fix this?

P.S. I use g++ 4.7 with option std=gnu++c11, if that matters.

Community
  • 1
  • 1
RPFeltz
  • 1,049
  • 2
  • 12
  • 21
  • This will definitely be closed as a duplicate, but in the meantime, the quick answer is to add `using Base::getTwo` into your `Derived` definition at class scope. – ildjarn Jul 14 '12 at 00:26

2 Answers2

1

Either:

class Derived : public Base {
public:
    using Base::getTwo; // Add this line
    int getValue() {
        // no matching function for call to ‘Derived::getTwo()’
        return getTwo();
    }
    int getTwo(int) {
        return 2;
    }
}

Or

        return Base::getTwo();
Robᵩ
  • 163,533
  • 20
  • 239
  • 308
  • Thanks! Could you please explain why this works, too? Or rather, why it doesn't otherwise? – RPFeltz Jul 14 '12 at 00:35
  • @RPFeltz: It is called *hiding*, and basically the process is that lookup starts in the closest context (starts inside `getValue()` method + ADL) and tries to find `getTwo()`, if it is not found, then the next scope is checked and so on. Once it finds the identifier in one context it stops the search. In your case, it finds `int getTwo(int)` inside your class, so it does not look into the base class for other overloads. The two alternative solutions are: bring the base overloads into the derived class scope with `using base::getTwo;`, so that it will be available in the class... – David Rodríguez - dribeas Jul 14 '12 at 00:56
  • ... and then overload resolution will pick the most appropriate overload. The alternative solution is to qualify the call with `base::getTwo()` which will tell the compiler that you want `getTwo()` from the base class context (i.e. avoid starting lookup in the current scope and jump searching for `getTwo` inside `base`) – David Rodríguez - dribeas Jul 14 '12 at 00:58
0

This is how the name lookup in C++ works:

namespace N1
{
    int getTwo();
    int getTwo(int, int);

    namespace N2
    {
        int getTwo(int);

        namespace N3
        {
            call getTwo(something char*);
        }
    }
}

The current context is N3. There is no getTwo on this layer. Ok, go to the upper layer. N2 contains one definition for getTwo. Compiler will try to use this definition and will not seach the upper context. The getTwo from N2 hides all definitions for getTwo on all upper layers. Sometimes this causes confusion with overloaded methods.

If you add using Base::getTwo;, you actually add a definition proxy to the inner context. The definitions of the upper context temsellves are not visible. But the proxy is visible.

Kirill Kobelev
  • 10,252
  • 6
  • 30
  • 51