当出现不明确的默认参数时,C++ 编译器会做什么?例如,假设有一个函数,例如:
void function(int a = 0, float b = 3.1);
void function(int a, float b =1.1, int c = 0);
以上是否被认为有歧义?如果不是,编译器在调用类似
function1(10)
之类的东西时会做什么(函数如何精确匹配)?
谢谢!
以下就可以了
void function(int a = 0, float b = 3.1);
void function(int a, float b =1.1, int c = 0);
下面的也可以
function(); // calls first function
但是下面的说法有歧义
function(1); // second and first match equally well
对于重载解析(告诉调用哪个函数的过程),未传递显式参数和使用默认参数的参数将被忽略。因此,编译器确实看到两个函数都具有用于上述调用的一个 int 参数,但无法做出决定。
以下内容格式不正确
void function(int a = 0, float b = 3.1);
void function(int a, float b =1.1);
虽然对于您问题中的代码,您声明了 two 函数(因为两个声明具有不同数量的参数),但在本示例中,您仅声明 one 函数。但它的第二个声明重复了参数的默认参数(甚至使用不同的值,但这不再重要)。这是不允许的。注意以下就可以了
void function(int a, float b = 3.1);
void function(int a = 0, float b);
出现在同一函数的同一作用域中的声明的默认参数集将被合并,并且仅适用于出现在同一作用域中的那些声明。所以以下是有效的
void function(int a = 0, float b = 3.1);
void function1() {
void function(int a, float b = 1.1);
function(0);
}
这会调用函数,并将
1.1
传递给 b
。
如果它们有不同的名称(如您的示例中所示),则不会产生歧义。 如果它们具有相同的名称(因此这是一次重载尝试),编译器会抱怨。
虽然事实证明你可以在不同的作用域中重新定义函数的默认参数(这对我来说是新闻......) - 但在相同的作用域中,你不能重新定义默认参数甚至是相同的值。来自 8.3.6/4“默认参数”:
对于非模板函数,默认 参数可以稍后添加 同一函数中的函数声明 范围。不同的声明 范围有完全不同的集合 默认参数。那是, 内部作用域中的声明不 获取默认参数 外部作用域中的声明,以及副作用域中的声明 反之亦然。在给定函数中 声明,所有参数后续 具有默认参数的参数 应提供默认参数 在本声明或之前的声明中。一个 默认参数不应是 由稍后的声明重新定义(不是 甚至相同的值)。
暧昧?您有两个完全独立的不同功能:
function1
和function2
。甚至每个函数中的参数数量也是不同的。这里没有任何歧义。当您要求编译器调用 function1(10)
时,它会调用 function1(10, 3.1)
。 function2
甚至没有进入图片。
如果是同一个函数,那么就不会仅仅因为在 C++ 中为同一参数多次指定默认参数(在同一翻译单元内)是非法的而出现歧义问题。即使您第二次指定相同的默认参数值,程序也是格式错误的
void foo(int a = 5);
void foo(int a = 5); // <- ERROR
我们可以做的是在不同的翻译单元中为同一个函数指定一组不同的默认参数。但这不会产生任何歧义,因为编译器只能看到一个翻译单元。在这种情况下,编译器永远不会知道任何潜在的“歧义”。
此外,任何以“C++ 编译器做什么...”开头的问题的答案始终是“取决于您正在谈论的编译器。”