简体   繁体   English

为什么不允许成员函数和非成员函数之间的函数重载?

[英]Why is function overloading between member functions and non-member functions not allowed?

In the following code:在以下代码中:

void overload() {}
struct Struct {
    void overload(int arg1) {}
    void member() {
        overload(1); //compiles
        overload(); //error: too few arguments [...] did you mean '::overloaded'?
    }
};

If I change struct to namespace I get similar results, just with a slightly different error message.如果我将struct更改为namespace我会得到类似的结果,只是错误消息略有不同。

Why can the compiler not select the non-member function via operator overloading when there is a member function with the same name?有同名成员函数时,为什么编译器不能通过运算符重载来选择非成员函数?

For reference, all of the following cases work as expected:作为参考,以下所有情况都按预期工作:

  • choosing between two non-members from a non-member (obviously)从非会员中选择两个非会员(显然)
  • choosing between two members from a member从一个成员中选择两个成员
  • choosing between two non-members from a member从一个成员中选择两个非成员

You're mostly asking why so rather than saying "because the language says so", lets show an example where your suggestion causes everything to fail.您主要是问为什么,而不是说“因为语言是这样说的”,让我们展示一个示例,说明您的建议导致一切失败。

Suppose I have a handy class in my github repo:假设我的 github 存储库中有一个方便的类:

struct HandyClass {
    void display(short c) {
        std::cout << c;
    }
    void doStuff() {
        display(3);
    }
};

And then some other developer in a different github repro makes a handy set of display functions:然后在不同的 github repro 中的其他一些开发人员制作了一组方便的显示功能:

void display(double v) {
    showWindowsPopup("Your score was %f", v);
}
void display(int v) {
    showWindowsPopup("Your score was %d", v);
}

You download both repros, and suddenly, HandyClass doesn't work right anymore:你下载了两个 repro,突然,HandyClass 不能正常工作了:

#include "displays.h"
#include "handyclass.h"

int main() {
    HandyClass a;
    a.doStuff(); //Why does this show a windows popup!?!?
}

Because you included the display headers first, then display(3) matched to ::display(int) instead of ::HandyClass::display(short) , because 3 is an int .因为您首先包含了显示标题,然后display(3)匹配到::display(int)而不是::HandyClass::display(short) ,因为3是一个int And much sadness occurs.和很多悲伤发生。

But with the official C++ lookup rules, this doesn't happen.但是根据官方的 C++ 查找规则,这不会发生。 Since my class has display functions, it will ignore functions outside the class, to prevent mistakes, so that HandyClass always does the same thing for everyone.由于我的类有display功能,所以会忽略类外的功能,防止出错,让HandyClass对每个人都做同样的事情。

Because the name overload in global scope can't be found by name lookup , it's hidden by Struct::overload .因为全局范围内的名称overload无法通过 名称查找找到,它被Struct::overload隐藏。 It has no chance to participate in overload resolution which happens later.它没有机会参与稍后发生的重载决议。

(emphasis mine) (强调我的)

name lookup examines the scopes as described below, until it finds at least one declaration of any kind, at which time the lookup stops and no further scopes are examined .名称查找按如下所述检查作用域,直到找到至少一个任何类型的声明,此时查找停止并且不再检查其他作用域

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

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