2013-06-15 2 views
5

В приведенном ниже коде я не могу понять, почему вызов «применить» сообщается как неоднозначный. Существует только одно приемлемое соответствие для предоставленного параметра (A_applicator::apply). Примечание. Я бы очень ценю ссылки на стандарт, который поможет мне определить поток разрешения, вызывающий эту двусмысленность.Почему этот виртуальный вызов неоднозначен?

struct A { }; 
struct B { }; 
struct A_D : public A { }; 

struct A_applicator { 
    virtual void apply(A) { } 
}; 
struct B_applicator { 
    virtual void apply(B) { } 
}; 
struct dual_applicator : public B_applicator, public A_applicator { 
}; 

int main() { 
    dual_applicator app; 
    A_D d; 
    app.apply(d); 
} 

(Online Demo)

+6

У вас есть класс, который получен из двух базовых классов, которые не переопределяют 'apply()'. Виртуальный вызов, который пытается найти дерево наследования и отвечает двум или более жизнеспособным параметрам, недействителен. Есть ваша двусмысленность. – CodaFi

+0

Действительно, я забыл свои предложения 'using'. Спасибо. –

ответ

6

Вы, кажется, думаете, что это не должно быть двусмысленно, потому что одна из функций не может быть вызвана, основываясь на типе аргументов. Но это не так, как работает разрешение имен C++.

Как это работает, более или менее: имя функции разрешено в набор перегрузки. И тогда список аргументов используется для выбора между функциями в этом наборе.

Ваша проблема в том, что первый шаг не может быть выполнен, так как имя apply, как оно используется, может ссылаться на два разных набора перегрузки, а компилятор не знает, какой из них использовать. Он даже не стал смотреть на параметры!

Решения просты:

A) Скажи, какую функцию вы хотите:

app.A_applicator::apply(d); 

B) Используйте using построить единый комплекс перегрузки функций-членов, поэтому ожидается разрешение с помощью аргументов используется ,

struct dual_applicator : public B_applicator, public A_applicator { 
    using A_applicator::apply; 
    using B_applicator::apply; 
}; 
+0

Это хорошее четкое объяснение. –

0

Класс dual_applicator не переопределяет виртуальную функцию apply.

Смежные вопросы