函数重载变得模棱两可

Function overloading getting ambiguous

重载函数时:

void add(int a)
{
    a=7;
    cout<<"int";
}
void add(double a)
{
    a=8.4;
    cout<<"double";
}
void add(int *b)
{
    *b=4;
    cout<<"pointer";
}
int main()
{
    char i='a';   //char
    add(i);
    return 0;
}

输出:int

尽管没有以 char 数据类型作为参数的函数,但它工作正常。

但是当编译成下面的代码时:

void add(char a)
{
    a='a';
    cout<<"int";
}
void add(double a)
{
    a=8.4;
    cout<<"double";
}
void add(int *b)
{
    *b=4;
    cout<<"pointer";
}
int main()
{
    int i=4;  //int
    add(i);
    return 0;
}

给出错误(编译器 gcc):

cpp|21|error: call of overloaded 'add(int&)' is ambiguous

这背后的逻辑是什么?以及如何跟踪此类代码的控制传递或输出?

原因是当没有精确的类型匹配时,编译器会寻找最接近的匹配。 这就是为什么当它是 - char i='a'; 最接近的匹配是 void add(int a)

但是当它是 int i=4; //int 时,现在有 2 个匹配项。所以这就是它模棱两可的原因。

A char 适合 int 而不会溢出或丢失精度,这解释了第一个代码。

但是 int 不适合 char(溢出)、double(缺乏精度)或 int*(不兼容类型)。

这个例子归结为整数提升和整数转换的区别。简而言之,促销是:

A prvalue of an integer type other than bool, char16_t, char32_t, or wchar_t whose integer conversion rank (4.13) is less than the rank of int can be converted to a prvalue of type int if int can represent all the values of the source type; otherwise, the source prvalue can be converted to a prvalue of type unsigned int. [...] These conversions are called integral promotions.

而整数转换更通用:

A prvalue of an integer type can be converted to a prvalue of another integer type. [...] The conversions allowed as integral promotions are excluded from the set of integral conversions.

为了重载解析,整数提升是比整数转换更好的转换。


在第一个例子中,我们有:

add(int );    // (1)
add(double ); // (2)
add(int* );   // (3)

并且正在用 char 呼叫。只有前两个是可行的,都涉及转换。 (1)涉及一个Integer Promotion,其中有rank Promotion。 (2)涉及到一个浮点数转换,有秩转换。 Promotion 的排名高于 Conversion,因此 (1) 无疑是首选。

现在,在第二个例子中,我们有:

add(char );   // (1)
add(double ); // (2)
add(int* );   // (3)

并且正在用 int 呼叫。再一次,只有前两个是可行的,并且都涉及转换。 (1) 这次涉及一个积分转换(因为char 的秩低于int)和 (2) 仍然涉及一个浮点积分转换,两者具有相同的秩:转换。由于我们有两个排名相同的转化,因此没有 "best" 转化,因此没有最佳可行候选者。因此,我们有一个模棱两可的决议。