使用浮点字面值调用重载函数会产生'ambiguos'错误

时间:2015-09-22 13:12:27

标签: c++ function overloading

编译以下代码时:

#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){

代码编译。那是为什么?

3 个答案:

答案 0 :(得分:5)

尝试不同的练习来理解这一点。删除两个重载中的任何一个都会使程序编译,尽管文字5.5没有标识匹配,是一个double值,它可以隐式转换为intfloat

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

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

答案 1 :(得分:4)

问题是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);

答案 2 :(得分: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