这个问题在这里已有答案:
我正在通过Sololearn学习C语言 . 我对函数重载有疑问
这是代码
#include<iostream>
using namespace std;
void printSomething(int x) {
cout << "I'm printing an integer " << x << endl;
}
void printSomething(float x) {
cout << "I'm printing a float " << x << endl;
}
int main() {
int a =3;
float b = 2.65;
printSomething(a);
printSomething(b);
return 0;
}
它给出了输出
I'm printing an integer 3
I'm printing a float 2.65
但是如果我在调用函数时直接给出参数
像这样
#include<iostream>
using namespace std;
void printSomething(int x) {
cout << "I'm printing an integer " << x << endl;
}
void printSomething(float x) {
cout << "I'm printing a float " << x << endl;
}
int main() {
printSomething(3);
printSomething(2.65);
return 0;
}
我得到以下错误
.. \ Playground:在函数'int main()'中:.. \ Playground:19:24:错误:调用重载'printSomething(double)'是模糊的printSomething(2.65); ^ .. \游乐场:19:24:注意:候选人是:.. \ Playground:5:6:注意:void printSomething(int)void printSomething(int x){^ .. \ Playground:9:6:注意: void printSomething(float)void printSomething(float x){^
但如果我改变
void printSomething(float x) {
cout << "I'm printing a float " << x << endl;
}
至
void printSomething(double x) {
cout << "I'm printing a float " << x << endl;
}
我会得到输出
I'm printing a float 2.65
为什么?但如果它只是整数就可以正常工作
#include<iostream>
using namespace std;
void printSomething(int x) {
cout << "I'm printing an integer " << x << endl;
}
void printSomething(float x) {
cout << "I'm printing a float " << x << endl;
}
int main() {
printSomething(3);
return 0;
}
结果
I'm printing an integer 3
为什么这不适用于浮点数
谢谢
3 回答
原因是转换规则和重载决策策略 . 如果C无法在参数上找到完全匹配,则会查找转换 . 最好的转换是隐式转换,即扩展(将数据类型转换为可以保存原始类型的所有值且可能更多的转换),然后缩小转换(转换为较小的数据类型,这可能会导致错误或某些值的精度损失),然后是用户定义的转换 .
由于2.65的文字是double类型,编译器会查找转换 . 有两个:double - > float和double - > int . 它们都在缩小,这意味着它们同样好 . 编译器无法选择最佳的编译器,因此报告错误 .
要解决这个问题,您可以:
像你一样为double定义重载
使用float literal(2.65f)而不是double
2.65
是 not afloat
literal,它是double
literal .因此编译器不知道您是否要将
double
转换为float
或int
,因此发出错误 .在你的第一种情况下,当编写
float b = 2.65;
时,编译器假定你知道你在做什么,并且使用b
调用重载是明确的 .如果您已经写了
printSomething(2.65f);
那么这也是明确的:2.65f
是float
字面值 .2.65
被认为是double
. 但是你没有提供过载void printSomething(double x)
. 因此编译器必须强制转换该值,并且它不知道它是否应该转换为float
或int
(两者都具有精度损失`) .如果你写
2.65f
它被认为是float
它应该工作 .