Почему вызов функции struct С++ неоднозначен, если есть унаследованные члены с разными параметрами?
Код ниже. У меня есть одна функция f() и одна единственная функция f (int) в моем классе D, так почему этот вызов неоднозначен, если обе функции имеют разные параметры?
struct A {
void f() {}
};
struct B: virtual A {
void f(int i) {}
};
struct C: virtual A {
void f() {}
};
struct D: B, C {
};
int main()
{
D d;
d.f(5); //ambiguous
}
Ответы
Ответ 1
Проблема здесь в том, что поиск имени члена происходит, прежде чем оценивать, какие функции являются жизнеспособными и применяя разрешение перегрузки. Когда поиск имени находит имена из двух или более несвязанных базовых классов, это считается неоднозначным поиском, который немедленно недействителен.
Подробнее см. неквалифицированный поиск имени в определениях членов класса. (Это не тот контекст, который у вас здесь, но те же правила применяются для выражения доступа к члену.)
Вы можете обойти это, указав базовый класс, в который хотите начать поиск, с использованием идентификатора qualit:
d.B::f(5);
Или вы можете сделать обе функции явно видимыми непосредственно в D
:
struct D: B, C {
using B::f;
using C::f;
};
Ответ 2
Вызов неоднозначен, поскольку обе базы A и C структуры D имеют функцию, называемую void f()
, даже если A f()
скрыта. Чтобы устранить неоднозначность, вы должны объявить f() в D.
struct A {
void f() {}
};
struct B: virtual A {
void f(int i) {} // < hides A::f(), even if signature is different,
};
struct C: virtual A {
void f() {} // < hides A::f()
};
struct D: B, C {
// f(...) functions in both base... which one hides the other?
};