Question

void f()
{}

struct A
{
    void f()
    {}
};

struct B : A
{
    B()
    {
        f(); // A::f() is always called, and ::f is always ignored 
    }
};

int main()
{
    B();
}

As the class B's designer, I MIGHT NOT know the fact that B's base class, i.e. A, has a member function A::f, I just know ::f, and call ::f is just what I want.

What I expects is the compiler gives an error because of ambiguity of calling f. However, the compiler always chooses A::f and ignore ::f. I think this might be a big pitfall.

I just wonder:

Why does the overload resolution of member functions exclude the global functions?

What's the rationale?

Était-ce utile?

La solution

As the class B's designer, I MIGHT NOT know B's base class

I don't agree.

Why does the overload resolution of member functions exclude the global functions?

Because the two overloads belong to two different scopes and compiler chooses the overload of same scope. Reading §3.4.1 . The f of inner (same) scope hide the outside's f.

What's the rationale?

To have a solid rule. We prefer to work in a same scope. Unless we explicitly want to call an object from somewhere else.

In a family by calling Alex, they expect their little boy Alex comes in, not the Alexander III of Macedon.

Autres conseils

That's just how overload resolution works, and it's good.

Imagine you really have a big project, tons of inter-dependencies, third party code and cross-module includes. In this huge mess, you have that one class you know works. It has been working perfectly for 5 years, it's efficient, easy to read and clean. You don't want to touch it. You then upgrade a modules, and start getting compiler errors. Oh no! That module (which you have no control over) introduced a new function DoAmazingStuff() at the global namespace. The same as a method name in our class. You're going to have to refactor it, since now you can no longer use the same name for a class member. Bummer!

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top