考虑以下函数定义
void fn(int a, int b)
{
//...
//...
}
void fn(int a, int b, int c = 0)
{
//...
//...
}
在主函数中,我使用 2 个参数调用 fn:
int main()
{
fn(10, 15);
return 0;
}
所以想知道编译器如何处理这种情况。
考虑以下函数定义
void fn(int a, int b)
{
//...
//...
}
void fn(int a, int b, int c = 0)
{
//...
//...
}
在主函数中,我使用 2 个参数调用 fn:
int main()
{
fn(10, 15);
return 0;
}
所以想知道编译器如何处理这种情况。
编译器无法知道,因此会引发错误:
prog.cpp: In function ‘int main()’: prog.cpp:15:12: error: call of
overloaded ‘fn(int, int)’ is ambiguous prog.cpp:15:12: note:
candidates are: prog.cpp:1:6: note: void fn(int, int) prog.cpp:7:6:
note: void fn(int, int, int)
该错误不会在声明时发生,而是在实际解决时发生。
除了其他答案,我猜,C++ 标准的以下规则也适用:
这些上下文中的每一个都以自己独特的方式定义了一组候选函数和参数列表。但是,一旦确定了候选函数和参数列表,最佳函数的选择在所有情况下都是相同的:3.如果存在最佳可行函数并且是唯一的,则重载解析成功并生成它作为结果。否则重载解析失败并且调用格式错误。当重载决议成功,并且最佳可行函数在使用它的上下文中不可访问(第 11 条)时,程序是非良构的。
- 首先,选择候选函数的子集(具有适当数量的参数并满足某些其他条件的函数)以形成一组可行的函数(13.3.2)。
- 然后根据将每个参数与每个可行函数的相应参数匹配所需的隐式转换序列 (13.3.3.1) 选择最佳可行函数。
顺便说一句,实际上有一种方法可以调用特定的重载:
#include <stdio.h>
int f(int a, int b)
{
printf("f - version 1\n");
return 0;
}
int f(int a, int b, int c = 10)
{
printf("f - version 2\n");
return 0;
}
int main(int argc, char * argv[])
{
int (* fn1)(int, int);
fn1 = f;
fn1(5, 10);
return 0;
}
虽然您可以声明它们,但如果您使用 fn(10,15) 调用它们,您可能会收到一个错误,指出这是一个模棱两可的调用,因为编译器不知道您要使用哪个。尽管这可能取决于您使用的编译器。
这不是有效的 C++ 代码,调用不明确。这是来自 GCC 的诊断:
In function ‘int main()’:
error: call of overloaded ‘fn(int, int)’ is ambiguous
note: candidates are: void fn(int, int)
note: void fn(int, int, int)
尽管一些编译器可以以某种方式处理这种情况(例如,在有歧义的情况下总是使用第二个定义而不是中止)。