简体   繁体   English

为什么成员函数的重载解析会排除全局函数?

[英]Why does the overload resolution of member functions exclude the global functions?

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, ie A , has a member function A::f , I just know ::f , and call ::f is just what I want. 作为类B的设计师,我可能不知道B的基类(即A )具有成员函数A::f的事实,我只知道::f ,而调用::f正是我想要的。

What I expects is the compiler gives an error because of ambiguity of calling f . 我期望编译器由于调用f的歧义而给出错误。 However, the compiler always chooses A::f and ignore ::f . 但是,编译器始终选择A::f并忽略::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? 有什么根据?

As the class B's designer, I MIGHT NOT know B's base class 作为B类的设计师,我可能不知道B的基类

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 . 阅读第3.4.1节。 The f of inner (same) scope hide the outside's f . 所述f的内(相同)范围隐藏外部的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 . 在一个打电话给亚历克斯的家庭中,他们希望自己的小男孩亚历克斯进来,而不是马其顿亚历山大三世

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. 它已经完美运行了5年,高效,易于阅读和清洁。 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. 该模块(您无法控制DoAmazingStuff()在全局名称空间中引入了新函数DoAmazingStuff() 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! mm!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM