Yiqun Cui
Yiqun Cui

Reputation: 55

An ambiguous function call in multiple inhertiance situation

class base1
{
public: 
    void printing()
    {
        cout << "Using base1" << endl;
    }
};

//base2 has a private version printing function 

class base2
{
    void printing()
    {
        cout << "Using base2" << endl;
    }
};

class derived :public base1, base2
{
    
};

int main()
{
    derived* d = new derived(); 
    d->printing(); 
}

The IDE told me that the call is ambiguous as "C++ does not consider the access specifiers of the functions when determining name resolution."

This seemed to be in conflict to what I read here: https://en.cppreference.com/w/cpp/language/overload_resolution#Viable_functions

In detail, overload resolution proceeds through the following steps:

Building the set of candidate functions.
Trimming the set to only viable functions.
Analyzing the set to determine the single best viable function (this may involve ranking of implicit conversion sequences).

So, the "viable" here only means some type check but it will not consider whether the function is accessible or even =delete'd?

Upvotes: -1

Views: 60

Answers (1)

user17732522
user17732522

Reputation: 76829

So, the "viable" here only means some type check but it will not consider whether the function is accessible or even =delete'd?

Yes, both are not relevant to whether or not a function is viable for a function call in overload resolution. The term is a technical one and its meaning can't be derived only from its meaning in general English.

This also makes sense if you consider that e.g. a = delete definition for a function would otherwise be identical to not declaring the function at all and would be redundant. The intention for it is to cause exactly this effect that overload resolution fails if the overload were to be chosen.

However, in your case it isn't even ambiguous overload resolution that causes the failure, but a step before that. Before overload resolution there is a name lookup to figure out what d->printing even is. It could be an overload set of functions or function templates or e.g. a member variable (which could have a operator()), etc.

Name lookup itself is already ambiguous, because the name is found in multiple base classes. You don't even get to the overload resolution aspect that considers the function call.

Upvotes: 1

Related Questions