c++ - 为什么这个重载的函数是模棱两可的?
问题描述
我试图重载这些函数并得到错误说函数调用不明确。
#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)
as should compiler convert doubles to ints and call volume(int, int, int)
or should convert int to double and call时,编译器会感到困惑volume(double, double, double)
。
对于高级读者
重载是如何工作的?
重载决议有 3 个步骤。
寻找候选函数: 与被调用函数同名的函数称为候选函数。在您的情况下,所有命名的函数
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,是候选函数(同名)。
它们都是可行的函数,因为可以通过转换进行调用并且都需要 2 个参数。
所以现在编译器逐个参数决定哪个函数最匹配。
如果只有且只有一个函数,则存在匹配:
1. 每个参数的匹配不比任何其他可行函数所需的匹配差
2. 至少有一个参数的匹配比任何其他可行函数提供的匹配更好
因此,当编译器通过可行函数的第一个参数检查第一个参数时,它会选择foo(double, double)
最佳匹配,但是当它检查第二个参数时,它会发现这foo(int, int)
是一个更好的匹配。
因此,该调用是模棱两可的。每个可行函数都更好地匹配调用的参数之一。
解决方案
要解决这种歧义,您需要确保编译器能够找到最佳匹配。因此,您需要显式转换参数。在您的情况下,您可以将双精度数转换为整数或将最后一个整数转换为双精度数。这个调用不会模棱两可:
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
}
笔记
通常,您不应尝试在函数调用中显式转换参数以进行重载。相反,您应该使用您正在尝试做的事情创建一个新的重载函数。但我希望你这样做只是为了学习,一切都很好。在项目中,您必须避免这些显式转换。
推荐阅读
- regex - pycharm 正则表达式替换字符串并保留原始匹配的字符串
- java - Java 包含多个库,在运行时决定使用哪一个?
- ios - PopToRootViewController 在底部显示黑条
- flutter - Flutter Navigator 未推入堆栈
- c# - 有没有办法通过索引从流文档中检索单个块?
- spring-boot - 由其他自定义授权服务器(SpringBoot2 和 OAuth2)进行身份验证时,OAuth2 客户端主体没有 GrantedAuthorities
- javascript - 为什么这要求方案不能按预期工作?
- jquery - 带有jquery的循环函数类名
- forms - 在编辑另一个文本字段 vue.js 时获取计算属性并传递其值
- javascript - D3更改选择/附加svg的顺序