在重载决策algorithm中如何确定模糊度?

我想了解重载parsing方法。

为什么这是模棱两可的:

void func(double, int, int, double) {} void func(int, double, double, double) {} void main() { func(1, 2, 3, 4); } 

但这不是?

 void func(int, int, int, double) {} void func(int, double, double, double) {} void main() { func(1, 2, 3, 4); } 

在第一种情况下,有2个确切的参数匹配和2个转换对1个完全匹配和3个转换,第二个情况下,有3个完全匹配和1个转换对1个完全匹配和3个转换。

那么为什么一个模棱两可,一个不是? 这里的逻辑是什么?

重载parsing规则只在所有匹配的集合上定义了部分顺序 – 如果过载F1不比F2更好匹配,则并不意味着F2F1更好匹配。 精确的部分顺序可以被认为是比较k维中的两个点,其中参数的数量是k(x_1, x_2,..., x_k) < (y_1, y_2,..., y_k) if x_i <= y_i for all i and x_j < y_j for at least one j 。 这正是标准定义的候选非模板函数的部分顺序。

让我们看看你的例子:

 void func(double, int, int, double) {} vvv vvv vvv better better equal void func(int, double, double, double) {} vvv vvv better equal 

所以超负荷都不会比其他的好。

在你的第二个例子中:

 void func(int, int, int, double) {} vvv vvv vvv vvv equal better better equal void func(int, double, double, double) {} vvv equal 

现在,第一个超载比第二个好,但是一个参数并不比第二个更差。 因此,没有歧义 – 部分顺序确实宣布第一个更好。

(上面的描述没有考虑函数模板,你可以在cppreference中find更多的细节。)

标准(§[over.match.best] / 1)的措词是:

让ICS i (F)表示将列表中的第i个参数转换为可行函数F的第i个参数的types的隐式转换序列。
如果对于所有参数i ,ICS i (F1)不是比ICS i (F2)更差的转换序列,则可行函数F1被定义为比另一可行函数F2更好的函数,然后
– 对于一些参数j ,ICS j (F1)是比ICS j (F2)更好的转换序列,

在你的第一个例子中,这两个函数在第一个testing中失败了。 对于第一个参数,第一个函数(采用double )具有比第二个函数更糟的转换顺序。 对于第二个参数,第二个函数的转换顺序比第一个要差(再次, int必须在一种情况下被提升为double ,而另一个则不能)。

因此,这两个函数都没有通过第一个规则,而且调用是不明确的。

在第二对函数之间,第一个函数的每个参数都至less和第二个函数的匹配参数一样好。 然后我们继续第二条规则,发现至less有一个论点(事实上是两个),第一个函数比第二个函数具有更好的转换(身份而不是升级)。

因此,第一个function是更好的匹配,并将被选中。

歧义由排名决定:

  1. 完全匹配:不需要转换,左值到右值转换,资格转换,用户定义的类types到同一类的转换
  2. 推广:整体推广,浮点推广
  3. 转换:积分转换,浮点转换,浮点积分转换,指针转换,指针到成员转换,布尔转换,派生类到用户定义的转换

完全匹配胜vs胜利vs转换。

在这个例子中:

 void func(int, bool, float, int){cout << "int,bool,float,int" << endl;} void func(int, bool, int, int){cout << "int,int,int,int" << endl;} int main() { func(1,1,3.4,4); } 

参数1( 1 )在两者上完全匹配
参数2( 1 )在两者上完全匹配
参数3( 3.4 )可以转换为float和int – 不确定性也不
参数4( 4 )是两者完全匹配的

但是,如果我们这样做: func(1,1,3.4f,4);
3.4f )现在完全匹配!
void func(int, bool, float, int)然后赢得战斗。