Устранение перегрузок виртуальных методов между базовыми классами

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++ говорит о разрешении перегруженных виртуальных методов в базовых классах?

2 ответа

Решение

Это действительно двусмысленность в соответствии со стандартом, но вы можете использовать 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 Объявление об использовании

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

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

class join_1_2 : public virtual base_1, public virtual base_2
{
public:
    using base_1::foo;
    using base_2::foo;
};
Другие вопросы по тегам