对重载函数错误的奇怪模糊调用

jam*_*gan 34 c++ visual-c++

我尝试着

void function(int y,int w)
{
    printf("int function");

}


void function(float y,float w)
{
    printf("float function");
}


int main()
{
    function(1.2,2.2);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我得到一个错误错误,如..

error C2668: 'function' : ambiguous call to overloaded function
Run Code Online (Sandbox Code Playgroud)

当我尝试调用function(1.2,2)function(1,2.2)打印为" int函数 "时

请说清楚什么时候function(float y,float w)打电话?

ggc*_*des 71

查看来自gcc的错误消息:

a.cpp:16: error: call of overloaded ‘function(double, double)’ is ambiguous
a.cpp:3: note: candidates are: void function(int, int)
a.cpp:9: note:                 void function(float, float)
Run Code Online (Sandbox Code Playgroud)

对任一函数的调用都需要截断,这就是为什么两者都不优先于另一个.我怀疑你真的想要void function(double y,double w).请记住,在C/C++中,文字和参数传递默认浮点类型是double,而不是float.

UPDATE

如果您真的不想将函数签名float更改为double,则可以始终使用键入float的文字.如果将后缀f添加到浮点数,则它们将是键入的float.

那么你的例子就是function(1.2f, 2f)function(1, 2.2f).

  • 因为下面没有其他答案给我这样一个明确的解决方案,所以我将我的赏金给予了法律. (3认同)

Alo*_*ave 36

什么是运算符重载?

Sbi着名的运营商重载常见问题解答非常详细.

为什么functionOP 中的两个版本允许存在?

请注意,它们采用不同的函数参数类型(intfloat),因此有资格作为有效的函数重载.

什么是重载分辨率?

它是通过编译器实现选择最合适的函数/运算符的过程.如果存在一个最好的可行函数并且是唯一的,则重载解析成功并将其作为结果产生.否则,重载解析失败,并且调用被视为格式错误,编译器提供诊断.编译器使用隐式转换序列来查找最佳匹配函数.

C++ 03标准13.3.3.1隐式转换:

隐式转换序列是一系列转换,用于将函数调用中的参数转换为被调用函数的相应参数的类型.

隐式转换序列可以是以下类别之一:

  • 标准转换序列(13.3.3.1.1)
  • 用户定义的转换序列(13.3.3.1.2)
  • 省略号转换序列(13.3.3.1.3)

请注意,对这些中的每一个进行排名以确定最佳可行功能.最好的可行功能是所有参数都具有比所有其他可行功能更好或相等排名的隐式转换序列的功能.标准在各个部分中详细说明了每一个.标准转换顺序与此案例相关,总结如下:

在此输入图像描述

有足够的重载分辨率背景.
让我们来看看OP中的代码示例:

function(1.2,2.2);
Run Code Online (Sandbox Code Playgroud)

重要规则: 1.2并且2.2是文字,它们被视为double数据类型.

在隐式转换序列映射期间:
具有double类型的函数参数文字都需要转换排名来调用floatint版本,而none是比其他更好的匹配,它们在转换排名上得分完全相同.编译器无法检测到最佳可行匹配,并且报告了歧义.

function(1.2,2);
Run Code Online (Sandbox Code Playgroud)

在隐式转换序列的映射:
一个函数参数的2具有精确匹配int功能版本,而另一个1.2具有一个转换秩.对于float作为参数的函数,两个参数的隐式转换序列具有转换等级.
因此,int版本得分比版本更好的功能float是最佳匹配并被调用.

如何解决重载歧义错误?

如果您不希望隐式转换序列映射将您抛弃,只需提供函数并以这种方式调用它们,以使参数完全匹配.由于精确匹配得分高于其他所有人,因此您可以确定所需的函数被调用.在您的情况下,有两种方法可以做到这一点:

解决方案1:

调用该函数,使参数与可用函数完全匹配.

function(1.2f,2.2f);
Run Code Online (Sandbox Code Playgroud)

由于1.2f2.2f被视为float类型,它们与float功能版本完全匹配.

解决方案2:

提供与被调用函数中的参数类型完全匹配的函数重载.

function(double, double){}
Run Code Online (Sandbox Code Playgroud)

由于1.22.2被视为double被调用函数,因此与此重载完全匹配.


chu*_*e x 7

如果您不想(如接受的答案中所述):

  • 使用浮点文字,例如 1.2f
  • 或将现有的float重载更改为double

您可以添加另一个调用float的重载:

void function(double y, double w)
{
    function((float)y, (float)w);
}
Run Code Online (Sandbox Code Playgroud)

main现在的代码将调用上面的函数,它将调用float重载.


Kri*_*Oza 5

上面示例中的函数重载具有不明确的调用,因为返回类型相同,并且函数调用中的第二个参数是double,可以将其视为int或float,因此编译器会混淆要执行的函数.

  • 返回类型与它无关. (5认同)