首页 文章

重载C中的函数[重复]

提问于
浏览
1

这个问题在这里已有答案:

我正在通过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 回答

  • 4

    原因是转换规则和重载决策策略 . 如果C无法在参数上找到完全匹配,则会查找转换 . 最好的转换是隐式转换,即扩展(将数据类型转换为可以保存原始类型的所有值且可能更多的转换),然后缩小转换(转换为较小的数据类型,这可能会导致错误或某些值的精度损失),然后是用户定义的转换 .

    由于2.65的文字是double类型,编译器会查找转换 . 有两个:double - > float和double - > int . 它们都在缩小,这意味着它们同样好 . 编译器无法选择最佳的编译器,因此报告错误 .

    要解决这个问题,您可以:

    • 像你一样为double定义重载

    • 使用float literal(2.65f)而不是double

  • 1

    2.65not a float literal,它是 double literal .

    因此编译器不知道您是否要将 double 转换为 floatint ,因此发出错误 .

    在你的第一种情况下,当编写 float b = 2.65; 时,编译器假定你知道你在做什么,并且使用 b 调用重载是明确的 .

    如果您已经写了 printSomething(2.65f); 那么这也是明确的: 2.65ffloat 字面值 .

  • 0

    2.65 被认为是 double . 但是你没有提供过载 void printSomething(double x) . 因此编译器必须强制转换该值,并且它不知道它是否应该转换为 floatint (两者都具有精度损失`) .

    如果你写 2.65f 它被认为是 float 它应该工作 .

相关问题