【问题标题】:Why does the overload resolution of member functions exclude the global functions?为什么成员函数的重载解析会排除全局函数?
【发布时间】:2013-10-26 08:34:29
【问题描述】:
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。我认为这可能是一个很大的陷阱。

我只是想知道:

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

原因是什么?

【问题讨论】:

    标签: c++ function namespaces overloading overload-resolution


    【解决方案1】:

    作为 B 类的设计者,我可能不知道 B 的基类

    我不同意。

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

    因为这两个重载属于两个不同的作用域,编译器选择了同一个作用域的重载。阅读§3.4.1。内部(相同)作用域的f 隐藏了外部的f

    原因是什么?

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

    在一个打电话给 Alex 的家庭中,他们希望他们的小男孩 Alex 进来,而不是 Alexander III of Macedon

    【讨论】:

      【解决方案2】:

      这就是重载解析的工作原理,很好

      想象一下你真的有一个大项目,大量的相互依赖,第三方代码和跨模块包含。在这个巨大的混乱中,你有一个你知道有效的课程。它已经完美运行了 5 年,它高效、易于阅读和清洁。你不想碰它。然后升级模块,并开始出现编译器错误。不好了!该模块(您无法控制)在全局命名空间中引入了一个新函数 DoAmazingStuff()。与我们类中的方法名称相同。您将不得不重构它,因为现在您不能再为类成员使用相同的名称。无赖!

      【讨论】:

      • 值得添加的参数仍然适用,即使两个 fs 具有不同的类型签名 - 因为该类可能依赖于将参数转换为 f
      猜你喜欢
      • 1970-01-01
      • 2014-02-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-17
      • 2013-09-04
      • 1970-01-01
      • 2017-05-13
      相关资源
      最近更新 更多