Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why doesn't private inheritance resolve ambiguity for static functions ? (tested in MSVC)

I'm wondering why a call to a static function is ambiguous, even when one of the two is obviously impossible to call as it is private. I was hoping I could use private / protected inheritance to help the compiler solve the ambiguity.

Is it specific to MSVC or is it somehow specified in the standard ?

struct A
{
    static int num() { return 0; }
};

struct B
{
    static int num() { return 1; }
};

struct C : public A, private B
{};

int main()
{
     C::num(); // Ambiguous access of num
}

The background is that I was trying a way of reusing an overloading behavior (the one in A) in many derived classes (C,D,E,F,G) by inheriting it, to adhere somehow to a rule of Don't Repeat Yourself.

like image 405
N0vember Avatar asked Dec 28 '14 18:12

N0vember


People also ask

How do you resolve ambiguity in inheritance?

Ambiguity in inheritance can be defined as when one class is derived for two or more base classes then there are chances that the base classes have functions with the same name. So it will confuse derived class to choose from similar name functions. To solve this ambiguity scope resolution operator is used “::”.

What is the point of private inheritance in C++?

protected inheritance makes the public and protected members of the base class protected in the derived class. private inheritance makes the public and protected members of the base class private in the derived class.

What is the effect of using private inheritance?

With private inheritance, public and protected member of the base class become private members of the derived class. That means the methods of the base class do not become the public interface of the derived object. However, they can be used inside the member functions of the derived class.


1 Answers

Yes it is specified in the C++ Standard, section §3.4 [basic.lookup]

The access rules (Clause 11) are considered only once name lookup and function overload resolution (if applicable) have succeeded

Name lookup doesn't care about accessibility : it finds both A::num and B::num, so there is an ambiguity for the compiler.

You can explicitly call A::num with :

C::A::num();

If you explicitly try to call B::num, then your compiler will indeed emit an access error :

C::B::num(); // Error

You can also explicitly bring the base name into scope within the derived class, which will fix the ambiguity :

struct C : public A, private B
{
    using A::num;    
};
like image 83
quantdev Avatar answered Sep 28 '22 08:09

quantdev