所以我知道不允许使用具有相同参数和名称的函数:
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
?
答案 0 :(得分:8)
从函数调用中选择要使用的正确函数的过程称为过载分辨率。调用函数时,编译器将搜索具有该名称的所有函数(重载),并将它们编译为重载集。简而言之,通过从参数中选择需要最少转换的函数来选择最佳匹配。
这些是编译器从a(c)
中选择的两个函数:
int a(const int& b);
int a( int& b);
选择第二个重载是因为第一个重载需要const
- 限定。您使用c
调用函数的变量是非const
,因此它与第二次重载完美匹配,并且可以绑定到非const
{{1}}参考。
答案 1 :(得分:2)
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
,因此它会更喜欢使用非const的函数参考。