c++ 为什么在指定默认参数时函数重载不起作用?

ykejflvf  于 2023-04-08  发布在  其他
关注(0)|答案(2)|浏览(119)

当没有指定默认参数时,函数重载起作用。
但是,为什么在指定默认参数时函数重载不起作用呢?
这个程序接受两个整数并比较它们以找出两者中较大的一个。
然后,它将最大值与之前获得的较大整数进行比较,并输出较小的值。
这是我写的代码

#include <iostream>
using namespace std;

int big(int a, int b);
int big(int a, int b, int max = 100);

int big(int a, int b) {
    if (a > b)
        if (a > 100)
        {
            return 100; 
        }
        else {
            return a; 
        }
    else {
        if (b > 100) {
            return 100; 
        }
        else
        {
            return b; 
        }
    }
}

int big(int a, int b, int max) {
    if (a > b) {
        if (a < max) {
            return a; 
        }
        else
        {
            return max; 
        }
    }
    else {
        if (b < max) {
            return b; 
        }
        else {
            return max; 
        }

    }
}
  
int main() {
    int x = big(3, 5); 
    int y = big(300, 60); 
    int z = big(30, 60, 50); 
    cout << x << ' ' << y << ' ' << z << endl;
    return 0;
}

当我调试我写的代码时,它说
E0308编译错误:重载函数的多个示例与参数列表匹配
我了解到,当函数参数不同时,函数重载可以工作。
在我的代码中,函数名是相同的,但函数参数是不同的:

(int x, int y) and (int x, int y, int max)

但它不起作用。
总而言之,为什么在指定默认参数时函数重载不起作用?

我使用的IDE:

Microsoft Visual Studio Community 2022(64位)-当前版本17.5.1

以下是期望结果:

1.变量xy具有第一个函数big(int x, int y)的返回值
1.变量z具有第二个函数big(int x, int y, int max = 100)的返回值
This Question是相关的,但我不明白如何解决是我想要的。

9q78igpj

9q78igpj1#

你已经有效地让这两个函数命名相同

int big(int a, int b) {}

int big(int a, int b, int max=100) {}

然后当你调用big(3,5) ....
您希望调用的big的确切版本是什么?第一个实现显式地接受两个参数,还是第二个实现可以接受两个或三个参数?
编译器帮了你一个忙,它会报错并告诉你它是不明确的。
正如我在评论中所说的,函数重载被高估了。只要显式地命名函数,就不会有任何歧义。
而且,整个实现可以简化为一个函数和两行代码

int big(int a, int b, int max=100) {
    int result = (a > b) ? a : b;
    return (result > max) ? max : result;
}

max的默认参数对我来说似乎是无害的,如果你把它作为一个没有重载的函数。

vkc1a9a2

vkc1a9a22#

这部分是不明确的,因为第二个函数声明有一个默认参数:

int big(int a, int b);
int big(int a, int b, int max = 100);

例如,当你调用big(20,30)时,big()的两个版本都可以使用。所以有两个候选者。
使用函数的第二个版本就足以使其在不重载的情况下工作。如下所示:

#include <iostream>
using namespace std;

// declare
int big(int a, int b, int max = 100);

// define
int big(int a, int b, int max) {
    if (a > b) {
        if (a < max) {
            return a;
        }
        else
        {
            return max;
        }
    }
    else {
        if (b < max) {
            return b;
        }
        else {
            return max;
        }

    }
}

int main() {
    int x = big(3, 5);
    int y = big(300, 60);
    int z = big(30, 60, 50);
    cout << x << ' ' << y << ' ' << z << endl;
    return 0;
}

如果你还想定义两个函数,我建议你删除默认参数。

#include <iostream>
using namespace std;

int big(int a, int b);
int big(int a, int b, int max);

int big(int a, int b) {
    if (a > b)
        if (a > 100)
        {
            return 100;
        }
        else {
            return a;
        }
    else {
        if (b > 100) {
            return 100;
        }
        else
        {
            return b;
        }
    }
}

int big(int a, int b, int max) {
    if (a > b) {
        if (a < max) {
            return a;
        }
        else
        {
            return max;
        }
    }
    else {
        if (b < max) {
            return b;
        }
        else {
            return max;
        }

    }
}

int main() {
    int x = big(3, 5);
    int y = big(300, 60);
    int z = big(30, 60, 50);
    cout << x << ' ' << y << ' ' << z << endl;
    return 0;
}

额外说明:关于声明和定义你的函数。因为你在同一个源文件中定义了函数int,并且在main()之前,也许你不需要声明然后定义。所以你可以跳过声明它。如果你将实现移动到另一个源文件或main()之后,然后声明它。更多信息:Link

相关问题