过载解析混乱

问题描述 投票:0回答:3

我不知道重载解析在这里是如何工作的!对于第一个片段,它解析为 OVERLOAD A,但对于第二个片段,它会引发错误“不明确的调用”。

代码1

#include <iostream>
using namespace std;
void doThings_A(int ,int ,double){ cout<<"first fxn"<<endl;}  //OVERLOAD A
void doThings_A(int ,double,double){ cout<<"second fxn"<<endl;} //OVERLOAD B
int main() {
    // Write C code here
    doThings_A(4,5,6);

    return 0;
}

代码 1 的输出:第一个 fxn

代码2


#include <iostream>
using namespace std;
void doThings_A(double ,int ,int){ cout<<"first fxn"<<endl;}
void doThings_A(int ,double,double){ cout<<"second fxn"<<endl;}
int main() {
    // Write C code here
    doThings_A(4,5,6);

    return 0;
}

代码 2 的输出:

error: call of overloaded 'doThings_A(int, int, int)' is ambiguous
    8 |     doThings_A(4,5,6);
      |     ~~~~~~~~~~^~~~~~~
/tmp/sI0f5j5PL7.cpp:4:6: note: candidate: 'void doThings_A(double, int, int)'
    4 | void doThings_A(double ,int ,int){ cout<<"first fxn"<<endl;}
      |      ^~~~~~~~~~
/tmp/sI0f5j5PL7.cpp:5:6: note: candidate: 'void doThings_A(int, double, double)'
    5 | void doThings_A(int ,double,double){ cout<<"second fxn"<<endl;}
c++ overloading
3个回答
0
投票

C++ 在这方面的设计方式(无论是选择重载还是模板特化、比较

concept
强度等)的一般原则是它 为不同的替代方案分配“分数”(基于参数的数量)如果我们谈论函数重载或其他任何东西,则需要隐式转换。

相反,要使 A 比 B 更好,A 必须在所比较的每个单独方面不更差,并且至少在一个方面更好。

对于函数重载,比较的“方面”是每个单独的参数是否需要隐式转换:

  • 在第一个片段中,两个重载对于参数 1 和 3 来说是等效的(即,没有一个比另一个更差),但是第一个重载相对于参数 2 更好。因此,第一个重载总体上更好。

  • 在第二个片段中,第一个重载相对于参数 2 和 3 更好,但第二个重载相对于参数 1 更好,因此存在歧义。


当然,还有更多细微差别,但一般原则仍然成立:


0
投票

这里的决定因素是(过载分辨率 - 最佳可行功能):

如果 F1 所有参数的隐式转换不比 F2 所有参数的隐式转换差,则确定 F1 是比 F2 更好的函数,并且

  1. F1 中至少有一个参数的隐式转换优于 F2 中该参数的相应隐式转换

让我们看看签名:

void doThings_A(int ,int ,double)   // 1
void doThings_A(int ,double,double) // 2

当使用三个

int
调用时,第一个和第三个参数对于 1 和 2 都同样有效 - 分别是匹配和浮点提升。

但在第二个参数中,1 是匹配,而 2 需要浮点提升。这意味着对于每个参数,1 都等于或优于 2,因此选择 1。

但是,在第二个示例中,我们有:

void doThings_A(double ,int ,int)   // 3
void doThings_A(int ,double,double) // 4

这里 3 更好地匹配第二个和第三个参数,而 4 更好地匹配第一个参数。这意味着没有明显更好的候选者,因此决议失败。


0
投票

在这两种情况下,两个重载

doThings_A
对于调用
doThings_A(4,5,6)
来说都是可行的函数,但在第一种情况下,一个是另一个“更好的函数”。

如果

F1

 的所有参数的隐式转换不比 
F2
 的所有参数的隐式转换差,则 
F1
被确定为比
F2
更好的函数,并且

  1. F1
    中至少有一个参数的隐式转换优于
    F2
  2. 该参数的相应隐式转换

在这两种情况下,最差的隐式转换(

int
double
)是相同的,因此必须考虑子句
1.
。让我们逐个比较案例:

CASE 1
           | arg1              | arg2                | arg3                |
CALL       | int               | int                 | int                 |
F1         | int (exact match) | int (exact match)   | double (conversion) |
F2         | int (exact match) | double (conversion) | double (conversion) |
WINS       | tie               | F1                  | tie                 |

至少有一个参数 (

arg2
) 的隐式转换更好,
F1
获胜并且是最佳可行函数。


CASE 2
           | arg1                | arg2                | arg3                |
CALL       | int                 | int                 | int                 |
F1         | double (conversion) | double (conversion) | int (exact match)   |
F2         | int (exact match)   | double (conversion) | double (conversion) |
WINS       | F2                  | tie                 | F1                  |

按照同样的规则,

F1
是比
F2
arg3
)更好的可行函数,并且
F2
是比
F1
arg1
)更好的可行函数。这导致两个函数的排名相等,因此出现不明确的调用错误。

© www.soinside.com 2019 - 2024. All rights reserved.