【问题标题】:Calling overloaded function with floating point literal yields 'ambiguos' error [duplicate]使用浮点文字调用重载函数会产生“歧义”错误[重复]
【发布时间】:2015-09-22 13:12:27
【问题描述】:

编译以下代码时:

#include <iostream>
using namespace std;

void print(int i){
    cout << i << endl;
}

void print(float i){
    cout << i << endl;
}

int main(){
    print(5);
    print(5.5)
    return 0;
}

我得到错误:

重载的'print(double)'调用不明确。

但是,如果我改变了

void print(float i){

void print(double i){

代码编译。这是为什么呢?

【问题讨论】:

  • 5.5double 文字常量 - 将其更改为 5.5f 它将与 float 一起使用。
  • “重载 'print(double)' 的调用不明确”表示您没有使用浮点数
  • 感谢大家的帮助

标签: c++ function overloading


【解决方案1】:

尝试不同的练习来理解这一点。删除这两个重载中的任何一个都会使程序编译,虽然没有与文字 5.5 的身份匹配,一个双精度值,它可以隐式转换为 intfloat

当两个重载都存在时,因为5.5 可以隐式转换为intfloat,所以两者都是可行的。编译器无法在两者之间做出决定,因此出现错误。

在将文字设为float5.5f 后,我们就有了身份匹配、float 重载,并且编译器的决策没有歧义。相反,保留文字 double5.5,将函数原型从 float 更改为 double 也可以,因为这也是身份匹配。

【讨论】:

  • 如果 5.5 不是浮点数,那么浮点数比是什么?对不起,我一直在 Python 中使用浮点数,而在 Python 5.5 中是浮点数
  • @HugoCornel Python 只有一种浮点类型。 C++ 有两种不同的类型,floatdouble
【解决方案2】:

问题是5.5 的类型是double。由于print 被重载,编译器将寻找最佳匹配来找出要调用的重载,这个过程称为overload resolution。这是一组非常复杂的规则,但在您的简单案例中会发生以下情况:

首先编译器会检查一个完全匹配,即一些void print(double);或类似的。

由于这不存在,它会考虑转化。 double 可以隐式转换为 intfloat,并且这些转换被认为是同样好的。

因此,编译器无法决定它应该调用哪个函数重载并抱怨调用不明确。

正如其他人已经提到的,您可以通过以下方式解决此问题 要么让输入类型完全正确:print(5.5f); 或添加一个与double 参数明确匹配的重载,例如

void print (double);
void print (const double&);
template <class T>
void print (T);

【讨论】:

    【解决方案3】:

    整数版本:

    void print(int i)
               ^^^ // This declaration wants an `int` type
    

    浮动版:

    void print(float i)
               ^^^^^ // This declaration wants a `float` type
    

    用法:

    print(5); // Calling print with `int`, finds the "Integer version"
    print(5.5); // '5.5' is a `double` type, which is neither an `int` type nor a `float` type
    

    由于指定了 double 类型并且没有 double 重载,因此需要转换为 intfloat 才能使用现有重载。

    使用现有的重载:

     print(5.5f); // Use a `float` literal (i.e., this is a `float` type)
     print(static_cast<float>(5.5)); // I'd recommend the former but this works
     print(static_cast<int>(5.5)); // Works but obviously truncates the value
    

    添加一个新的重载(而不是更新现有的float 重载):

    void print(double i); // A new overload declaration
    

    【讨论】:

    • "'5.5' 是一个double 类型,既不匹配“整数版本”也不匹配“浮点版本””。实际上它两者都匹配,但两者都被赋予了转换等级(从重载解决的角度来看同样好)
    • @PiotrSkotnicki 是的,你说得对,我的措辞很糟糕。我打算传达double 不是floatint,每个都需要一次转换。我会尽量让它更清楚。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-04
    • 1970-01-01
    • 2016-07-24
    • 2014-01-13
    相关资源
    最近更新 更多