为什么这种重载函数是不明确的
Why does this overloaded functions is ambiguous?
我试图重载这些函数,但收到一个错误,说函数调用不明确。
#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转换为int并调用volume(int, int, int)
,还是应该将int转换为double并调用volume(double, double, double)
。
适用于高级读卡器
过载是如何工作的
解决过载问题有三个步骤。
-
查找候选函数:与被调用函数同名的函数被称为候选函数。在您的案例中,所有名为
volume
的函数都是候选函数,因为您将volume(..)
称为 -
寻找可行函数:一个函数必须满足两个测试才能可行首先,该函数的参数数量必须与调用中的参数数量相同。(默认参数除外)。其次,每个参数必须匹配--或者可以转换为其相应参数的类型。在您的情况下,
volume(int,int,int) and volume(double, double, double)
是可行的函数。 -
找到最佳匹配(如果有的话):重载解析的最后一步确定与参数最匹配的可行函数这里最好的意思是——精确的类型匹配比需要从参数类型转换为参数类型的匹配要好。在你的情况下,没有最好的匹配。您的调用
volume(double, double, int)
与任何可行的函数都不匹配。
多个参数的问题
让我们来看看这个比较简单的案例
void foo(int x, int y);
void foo(double x, double y);
假设我们以的身份打电话
foo(4.2, 5) //double and int
上面两个foo,是候选函数(同名)。
它们都是可行的函数,因为可以通过转换进行调用,并且都有两个参数。
所以现在编译器通过一个参数一个参数地决定哪个函数最匹配。
如果只有并且只有一个功能,则存在匹配:
1.每个参数的匹配不比任何其他可行函数所需的匹配差
2.至少有一个参数的匹配比任何其他可行函数提供的匹配更好
因此,当编译器通过可行函数的第一个参数来检查第一个参数时,它选择foo(double, double)
是最佳匹配,但当它检查第二个参数时发现foo(int, int)
是更好的匹配。
因此,调用不明确。每个可行的函数在调用的一个参数上更好地匹配
解决方案
要解决这种歧义,您需要确保编译器能够找到最佳匹配。因此,您需要显式地转换参数。在您的情况下,您可以将double转换为int,也可以将last int转换为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
}
注意
一般情况下,您不应该尝试在函数调用中显式转换参数以进行重载。相反,你应该用你试图做的事情来创建一个新的重载函数。但我希望你这样做只是为了学习,一切都好。在项目中,必须避免这些显式转换。
GCC扫描仪正在将3
标记为int
,而不是double
将volume(2.0,9.7,3)
更改为volume(2.0,9.7,3.0)
取决于这两个功能:
double volume(double a, double b, double c)
double volume(int a, int b, int c)
您可以使用volume(2.0,9.7,3.0)
或volume(2,9,3)
如果有任何问题,请在下面评论
在volume(2.0,9.7,3)
中,2.0
和9.7
都是double
类型的文字值,但3
是int
类型的。
因此,编译器在您提供的volume()
版本中有两个同样可行的选项;
-
将两个
double
值转换为int
,并调用接受三个int
参数的volume()
版本。 -
将
int
值转换为double
,并调用接受三个double
参数的volume()
版本。
这两个选项都同样可行-根据语言规则,没有理由选择其中一个,因为在这两种情况下都有转换。因此出现了错误消息。
为了使编译器变得明确,您需要通过确保三个参数都具有相同的类型来消除歧义,因为可以在两个函数之间进行选择,这两个函数都具有相同类型的三个参数(double
或int
)。一种方式是提供三个int
值(例如,volume(2,9,3)
)或三个double
值(例如volume(2.0, 9.7, 3.0)
)。
编译器尝试进行一些隐式转换(double
到int
),这里有2个匹配的
double volume(int a, int b, int c)
double volume(double a, double b, double c)
将cout<<volume(2.0,9.7,3)<<endl
更改为cout<<volume(2.0,9.7,3.0)<<endl
- 为函数定义符号不明确的指针参数
- 父类的私有函数会导致对具有相同名称和相似参数的子类中的公共函数的不明确调用
- 对重载函数find_first_not_of的不明确调用
- 调用'Node'构造函数是不明确的
- "fpclassify":对重载函数的不明确调用
- 删除全局隐式函数 - 避免使用不明确的运算符
- 不明确的函数模板
- 错误:使用复制和交换习惯用法的交换函数中"operator="的重载不明确
- 为什么这种重载函数是不明确的
- 对函数的重新定义和不明确的调用具有数组参数
- C++ 函数名称不明确
- 为什么调用具有通用或 r 值引用的重载覆盖函数是不明确的?
- C++ 函数重载不明确,没有自动类型转换
- 不明确的函数声明
- 函数模板和不明确的模板参数
- 重载调用是不明确的:一对内联映射作为构造函数参数
- 使用 -pedantic 编译时采用 std::reference_wrapper 的不明确构造函数
- C++中来自不同基类的不明确函数
- 对自身的不明确函数调用
- C++ 中的不明确函数