c++ - 为什么这个重载函数是模棱两可的?

标签 c++ function

我试图重载这些函数,但出现错误,指出函数调用不明确。

#include <iostream>
using namespace std;
double volume(int a){
    return a*a*a;
}
double volume(int a, int b, int c){
    return b*c*a;

}
double volume(int a, int b){
    return a*a*b;
}
double volume(double a, double b, double c){
    return a*b*c*2.5;
}
int main(){
    cout<<volume(2)<<endl;
    cout<<volume(2,3)<<endl;
    cout<<volume(2,2,3)<<endl;
    cout<<volume(2.0,9.7,3)<<endl;//error here
    return 0;
}

我得到的错误是这样的

错误:重载“volume(double, double, int)”的调用不明确

最佳答案

当您调用 volume(double, double, int) 时编译器感到困惑,因为编译器应该将 double 转换为整数并调用 volume(int, int, int) 或者它是否应该将 int 转换为 double 并调用 volume(double, double, double)


高级读者

重载是如何工作的?

重载解析有 3 个步骤。

  1. 寻找候选函数 : 与调用函数同名的函数称为候选函数。在您的例子中,所有名为 volume 的函数都是候选函数,因为您调用了 volume(..)

  2. 寻找可行的功能: 函数必须满足两个测试才能可行首先,函数的参数数量必须与调用中的参数数量相同。 (默认参数除外)。其次,每个参数必须匹配或可转换为其对应参数的类型。在您的情况下,volume(int,int,int) 和 volume(double, double, double) 是可行的函数。

  3. 找到最佳匹配(如果有的话): 重载决议的最后一步确定与参数最匹配的可行函数。 这里最好的意思是——精确的类型匹配比需要从实参到参数类型转换的匹配要好。在您的情况下,没有最佳匹配。您的调用 volume(double, double, int) 与任何可行的函数都不匹配。


多个参数的问题

让我们看一个更简单的例子

void foo(int x, int y);
void foo(double x, double y);

假设我们调用

foo(4.2, 5) //double and int

上面两个foo,是候选Functions(同名)。

而且它们都是可行的函数,因为调用可以通过转换进行,并且都带有 2 个参数。

所以现在编译器逐个参数地决定哪个函数最匹配。

如果只有且只有一个函数,则存在匹配:

1。每个参数的匹配并不比任何其他可行函数所需的匹配差

2。至少有一个参数匹配优于任何其他可行函数提供的匹配

因此,当编译器根据可行函数的第一个参数检查第一个参数时,它选择 foo(double, double) 是最佳匹配,但是当它检查第二个参数时,它发现 foo(int, int) 是更好的匹配。

因此调用不明确。每个可行的函数都更好地匹配调用的参数之一。


解决方案

要解决此类歧义,您需要确保编译器能够找到最佳匹配。所以你需要明确地转换参数。在您的情况下,您可以将 double 转换为整数或将最后一个整数转换为 double 。这个调用不会有歧义:

volume(2.0, 9.7, static_cast<double>(3));

为什么 static_cast?好吧,一般来说,你可以直接写 3.0,它会工作正常,但你不能用一些变量来做,比方说

int x = 10;
float a= 2.1, b=4.8;
for(int t=1;t<=x;t++){
   volume(a,b,static_cast<double>(t));
   //do something with t here 
}

注意

一般情况下,您不应尝试显式转换函数调用中的参数以进行重载。 相反,你应该用你正在尝试做的事情创建一个新的重载函数。但我希望你这样做只是为了学习,没关系。在项目中,您必须避免这些显式转换。

关于c++ - 为什么这个重载函数是模棱两可的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51452831/

相关文章:

PHP:以等号作为参数的函数?

C++ 重新定义变量,全局命名空间被污染,我不知道为什么

angular - matTooltip 和 [matTooltip] 有什么区别?

php - 在PHP中的函数中加载全局变量

C++ 指针有帮助吗?

javascript - 如何交错执行2个javascript函数?

javascript - 高阶函数引用JS

c++ - 使用函数定义作为友元声明时,clang 和 gcc 之间的行为差​​异

c++ - 洗车队列问题

C++:无法从派生类访问 protected 成员