关于c ++:为什么成员函数的重载解析不包括全局函数?

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
void f()
{}

struct A
{
    void f()
    {}
};

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

int main()
{
    B();
}

作为类B的设计者,我可能不知道B的基类,即A有一个成员函数A::f,我只知道::f,调用::f正是我想要的。

我所期望的是编译器由于调用f的模糊性而出错。但是,编译器总是选择A::f,而忽略::f。我认为这可能是一个很大的陷阱。

我只是想知道:

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

理由是什么?


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

我不同意。

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

因为这两个重载属于两个不同的作用域,所以编译器选择相同作用域的重载。阅读第3.4.1节。内部(相同)范围的f隐藏外部的f

What's the rationale?

有一个坚实的规则。我们更喜欢在同一个范围内工作。除非我们明确地想从其他地方调用对象。

在一个叫亚历克斯的家庭里,他们希望他们的小儿子亚历克斯进来,而不是马其顿的亚历山大三世。


这就是超负荷分辨率的工作原理,而且很好。

假设您真的有一个大项目,大量的相互依赖,第三方代码和跨模块包括。在这一团糟的情况下,你有一门你知道的课可以用。它已经完美运行了5年,它是高效的,易于阅读和清洁。你不想碰它。然后升级模块,并开始获取编译器错误。哦不!该模块(您无法控制)在全局命名空间中引入了一个新的函数DoAmazingStuff()。与类中的方法名相同。您将不得不重构它,因为现在您不能再为类成员使用相同的名称。真倒霉!