为什么允许这样做?

BWG*_*BWG 2 c++ overloading const reference

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

int a(int b) {
    return b;
}
int a(int b) {
    return b;
}

int main() {
    int c = a(4);
}
Run Code Online (Sandbox Code Playgroud)

以上内容不会编译.但后来我开始思考,如果我通过引用传递一个,然后按值传递一个怎么办?

int a(int b) {
    return b;
}
int a(int& b) {
    return b;
}

int main() {
    int c = a(4);
}
Run Code Online (Sandbox Code Playgroud)

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

int main() {
    int c = a(4);
    a(c);
}
Run Code Online (Sandbox Code Playgroud)

它将无法编译,我假设因为c可以传递给任一函数,所以编译器不知道要调用哪个函数.

那怎么样......这个?

int a(const int& b) {
    return b;
}
int a(int& b) {
    return b;
}

int main() {
    int c = a(4);
    a(c);
}
Run Code Online (Sandbox Code Playgroud)

这确实编译.为什么?我期望它不会,因为c可以传递到第一和第二a.我有一些误解吗?

我的问题具体是,为什么这个(下面的代码)不能编译,最后一个怎么做?

int a(int b) {
    return b;
}
int a(int& b) {
    return b;
}

int main() {
    int c = a(4);
    a(c);
}
Run Code Online (Sandbox Code Playgroud)

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

0x4*_*2D2 8

从函数调用中选择要使用的正确函数的过程称为" 过载分辨率".调用函数时,编译器将搜索具有该名称的所有函数(重载)并将它们编译为重载集.简而言之,通过从参数中选择需要尽可能少转换的函数来选择最佳匹配.

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

int a(const int& b);
int a(      int& b);
Run Code Online (Sandbox Code Playgroud)

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