2015-12-16 6 views
4

Visual Studio 2013.Устранение виртуального метода перегружает через базовые классы

Дано:

class base_1 
{ 
public: 
    virtual void foo(int) = 0; 
}; 

class base_2 
{ 
public: 
    virtual void foo(int, double) = 0; 
}; 

class join_1_2 : public virtual base_1, public virtual base_2 
{}; 

У меня есть раковина:

void sink(join_1_2 &param) 
{ 
    param.foo(42, 3.14); 
} 

Но я получаю следующие ошибки компилятора:

ошибка C2385: двусмысленный доступ к 'foo'

может быть 'Foo' в

база 'base_1' или может быть 'Foo' в базе '' base_2

ошибка C2660: 'base_1 :: Foo': функция не принимает 2 аргументы

ошибка C3861: 'Foo': идентификатор не найден

Я знаю, что эту проблему можно решить с:

param.base_2::foo(42, 3.14); 

Но, как вы можете себе представить, виртуальное наследование - это уже один грех, с которым я должен жить. Я, вероятно, собираюсь написать адаптер. Но я не понимаю, что мешает компилятору пытаться разрешить foo в base_2. Мой коллега полагает, что это ошибка компилятора, но я не так быстро обвиняю поставщика.

Что говорит спецификация C++ о разрешении перегруженных виртуальных методов в базовых классах?

ответ

4

Это действительно неоднозначность в соответствии со стандартом, но вы можете использовать using или указать базовый класс явно:

class join_1_2 : public virtual base_1, public virtual base_2 
{ 
public: 
    using base_1::foo; 
    using base_2::foo; 
}; 

void sink(join_1_2 &param) 
{ 
    param.base_2::foo(42, 3.14); 
} 

7.3.3 с использованием декларации

Для целей перегрузки, функции, которые вводятся с помощью объявления-объявления в производный класс , будут обрабатываться так, как если бы они были членами производного класса.

4

Правило большого пальца состоит в том, что функции в разных областях не перегружаются - здесь наши foo s находятся в разных областях. Если вы хотите их перегрузкой, вы хотите, чтобы привести их в с использованием декларирование:

class join_1_2 : public virtual base_1, public virtual base_2 
{ 
public: 
    using base_1::foo; 
    using base_2::foo; 
}; 
+0

1. Вы могли бы предоставить некоторые цитаты из этого правила.? 2. Есть ли другой способ получить эту ситуацию без поиска класса/множественного наследования? –