El compilador no encuentra la sobrecarga de la función correcta [duplicado]

Dec 11 2020

Tengo una pequeña clase base que define 3 sobrecargas para una función. La sobrecarga A llama a la sobrecarga B, que es puramente virtual, y su implementación en la clase derivada llama a la sobrecarga C.

Mi código completo es el siguiente:

struct Base {
        int func(int a) {return func(a, a+1);}
        int func(int a, int b, int c) {return a+b+c;}
        virtual int func(int a, int b)=0;
};

struct Derived : public Base {
        int func(int a, int b);
};

int Derived::func(int a, int b) {
        return func(a,b,a+b);
}

int main(int argc, char* argv[]) {
        Derived d;
        d.func(1);
        return 0;
}

Este código produce los errores:

test.cpp: In member function ‘virtual int Derived::func(int, int)’:
test.cpp:12:21: error: no matching function for call to ‘Derived::func(int&, int&, int)’
   12 |  return func(a,b,a+b);
      |                     ^
test.cpp:11:5: note: candidate: ‘virtual int Derived::func(int, int)’
   11 | int Derived::func(int a, int b) {
      |     ^~~~~~~
test.cpp:11:5: note:   candidate expects 2 arguments, 3 provided
test.cpp: In function ‘int main(int, char**)’:
test.cpp:17:10: error: no matching function for call to ‘Derived::func(int)’
   17 |  d.func(1);
      |          ^
test.cpp:11:5: note: candidate: ‘virtual int Derived::func(int, int)’
   11 | int Derived::func(int a, int b) {
      |     ^~~~~~~
test.cpp:11:5: note:   candidate expects 2 arguments, 1 provided

¿Por qué el compilador no encuentra la sobrecarga correcta dos veces? (una vez en la llamada a sobrecargar C en la clase derivada, y una vez al llamar a la sobrecarga A en la principal)

Respuestas

2 super Dec 11 2020 at 12:42

Si declara una función en una clase derivada con el mismo nombre que en la clase base, la declaración en la clase derivada sombreará las funciones en la clase base.

Entonces Derived, el único visible funces el (int, int)uno.

Una forma fácil de resolver esto es introducir las funciones de la clase base en el conjunto de sobrecarga con using.

struct Derived : public Base {
        using Base::func; // All the func overloads are now pulled into Derived's scope
        int func(int a, int b);
};