4

Visual Studio 2013.

Given:

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

I have a sink:

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

But I get the following compiler errors:

error C2385: ambiguous access of 'foo'

could be the 'foo' in base 'base_1'

or could be the 'foo' in base 'base_2'

error C2660: 'base_1::foo' : function does not take 2 arguments

error C3861: 'foo': identifier not found

I know I can resolve this issue with:

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

But as you can imagine, virtual inheritance is already one sin too many I have to live with. I'm probably going to write an adapter. But I don't understand what is preventing the compiler from trying to resolve foo in base_2. My colleague believes it to be a compiler error, but I'm not so quick to blame the vendor.

What does the C++ spec say about resolving overloaded virtual methods across base classes?

curiousguy
  • 8,038
  • 2
  • 40
  • 58
Matthew Reddington
  • 1,409
  • 3
  • 13
  • 24

2 Answers2

4

This is indeed ambiguity according to the standard, but you can use using or specify the base class explicitly:

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 The using declaration

For the purpose of overload resolution, the functions which are introduced by a using-declaration into a derived class will be treated as though they were members of the derived class.

AlexD
  • 32,156
  • 3
  • 71
  • 65
4

The rule of thumb is that functions in different scopes don't overload - here our foos are in different scopes. If you want them to overload, you'll want to bring them in with a using-declaration:

class join_1_2 : public virtual base_1, public virtual base_2
{
public:
    using base_1::foo;
    using base_2::foo;
};
Barry
  • 286,269
  • 29
  • 621
  • 977
  • 1. could you provide some quotes to the rule.? 2. Is there any other way to get this situation without class member lookup/multiple inheritance.? – Volodymyr Boiko May 28 '17 at 15:56