Компилятору не удается найти правильную перегрузку функции [дубликат]

Dec 11 2020

У меня есть небольшой базовый класс, который определяет 3 перегрузки для функции. Перегрузка A вызывает перегрузку B, которая является чисто виртуальной, а ее реализация в производном классе вызывает перегрузку C.

Мой полный код выглядит следующим образом:

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;
}

Этот код дает ошибки:

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

Почему компилятору дважды не удается найти правильную перегрузку? (один раз при вызове перегрузки C в производном классе и один раз при вызове перегрузки A в основном)

Ответы

2 super Dec 11 2020 at 12:42

Если вы объявляете функцию в производном классе с тем же именем, что и в базовом классе, объявление в производном классе затеняет функции в базовом классе.

Итак Derived, единственное видимое func- это (int, int)один.

Один из простых способов решить эту проблему - перетащить функции базового класса в набор перегрузки с помощью 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);
};