【问题标题】:Why is function overloading between member functions and non-member functions not allowed?为什么不允许成员函数和非成员函数之间的函数重载?
【发布时间】:2020-02-03 02:57:20
【问题描述】:

在以下代码中:

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

如果我将struct 更改为namespace,我会得到类似的结果,只是错误消息略有不同。

当有同名的成员函数时,为什么编译器不能通过运算符重载选择非成员函数?

作为参考,以下所有情况均按预期工作:

  • 从一个非成员中选择两个非成员(显然)
  • 在成员中的两个成员之间进行选择
  • 在成员中的两个非成员之间进行选择

【问题讨论】:

  • 简短的回答是因为这就是 C++ 的工作方式。重载解析的查找规则是结构化和严格的。逐步尝试每个范围。当在一个范围内找到匹配的符号时,就会发生重载决议。如果重载解析失败,则代码格式错误,并且不会继续查找。 ADL 引入了一些错综复杂的内容,但这是一个简单的总结。也许有人可以提供标准中相关引用的摘要......但这就是 C++ 的工作原理,仅此而已。
  • 这样编写标准是否有实际原因,还是只是语言设计疏忽?
  • using ::overload; 放入member。这是一个有意的决定,如果您碰巧在此之前包含一些其他标头,您不希望 member() 的行为发生变化

标签: c++ overloading


【解决方案1】:

你主要是问为什么,而不是说“因为语言是这样说的”,让我们举一个例子,你的建议会导致一切都失败。

假设我的 github 存储库中有一个方便的类:

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

然后另一个 github repro 中的其他开发人员制作了一组方便的显示功能:

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

你下载了两个副本,突然,HandyClass 不再正常工作了:

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

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

因为您首先包含了显示标题,然后display(3) 匹配到::display(int) 而不是::HandyClass::display(short),因为3int。并且发生了很多悲伤。

但使用官方 C++ 查找规则,这不会发生。由于我的班级有display的函数,它会忽略类外的函数,防止出错,让HandyClass总是为每个人做同样的事情。

【讨论】:

  • 虽然这种推理是有道理的,但令我感到不安的是,它同样适用于根本不涉及结构、类或命名空间的情况。
  • @Stuntddude 你的意思是如果有人将随机方法添加到全局命名空间?是的。事实上,这就是为什么我们有命名空间。这也是 Java 禁止全局方法的原因。还有为什么微软#define max 超级烦人。
【解决方案2】:

由于name lookup无法在全局范围内找到名称overload,因此Struct::overload将其隐藏。它没有机会参与稍后发生的重载决议。

(强调我的)

名称查找检查如下所述的范围,直到找到至少一个任意类型的声明,此时查找停止并且不再检查范围

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-06-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-20
    • 1970-01-01
    相关资源
    最近更新 更多