为什么允许这样做

Why is this allowed?

本文关键字:这样做 为什么      更新时间:2023-10-16

所以我知道不允许使用相同参数和名称的函数:

int a(int b) {
    return b;
}
int a(int b) {
    return b;
}
int main() {
    int c = a(4);
}

上面的内容不会编译。但后来我开始思考,如果我通过了一个参考,一个通过了价值呢?

int a(int b) {
    return b;
}
int a(int& b) {
    return b;
}
int main() {
    int c = a(4);
}

上面确实编译了,我想是因为你不能通过引用将4传递给,所以它假设你想要第一个a,这意味着编译器可以区分你想要调用哪个函数。如果我将main更改为:

int main() {
    int c = a(4);
    a(c);
}

我认为它将无法编译,因为c可以传递给任何一个函数,所以编译器不知道该调用哪个函数。

但是。。。这个?

int a(const int& b) {
    return b;
}
int a(int& b) {
    return b;
}
int main() {
    int c = a(4);
    a(c);
}

这是可编译的。为什么?我预计不会,因为c可以传递给第一个和第二个a。我有什么误解吗?

我的问题是,为什么这个(下面的代码(不编译,而最后一个编译?

int a(int b) {
    return b;
}
int a(int& b) {
    return b;
}
int main() {
    int c = a(4);
    a(c);
}

如果我是编译器,并且我可以根据参数匹配的程度来选择调用哪个函数,那么对于调用a(c),我可以从第一个和第二个中进行选择。在这个例子中,有什么原因不能选择第一个或第二个a吗?

从函数调用中选择要使用的正确函数的过程称为重载解决方案。调用函数时,编译器会搜索所有具有该名称的函数(重载(,并将它们编译到重载集中。简单地说,通过从参数中选择需要尽可能少转换的函数来选择最佳匹配。

这是编译器从a(c)中选择的两个函数:

int a(const int& b);
int a(      int& b);

选择第二个过载是因为第一个过载需要const资格。用于调用函数的变量c是非const,因此它与第二个重载完全匹配,并且可以绑定到非const引用。

int a(const int& b) {
    return b;
}
int a(int& b) {
    return b;
}
int main() {
    int c = a(4);
    a(c);
}

当你用a(4)调用它时,4是一个文本,只有你的版本使用const reference才能绑定它,所以这就是被调用的版本。

现在,当您调用a(c)时,您得到的c非常量int,因此它更喜欢使用非常常量引用的函数。