【问题标题】:why does calling an overloaded function with arguments that don't match still work为什么使用不匹配的参数调用重载函数仍然有效
【发布时间】:2019-12-30 14:58:16
【问题描述】:

我无法解释为什么第二次调用 (B) 没有给出任何错误,因为有两个 char 元素,并且没有与此调用确定的匹配项。

为什么叫第二版(2.,而不是第一版(1.)?

我注意到有一些自动转换。我不明白为什么'a' 被提升为int 而'c' 不是。

// 1.
int fun(int a, int b)
{
    return a + b;
}

// 2.
int fun(int a, char b)
{
    return b - a;
}

// 3 
int fun(float a, float b)
{
    return a * b;
}

int main() {

    //      A.          B.              C.
    cout << fun(1,0) << fun('a','c') << fun(2.f,2.f);

    return 0;
}

【问题讨论】:

  • 谢谢!什么是 TLDR?
  • 它代表“太久没读”。某事物的 TLDR 版本是指某事物的较短版本或简短摘要。

标签: c++ function overloading


【解决方案1】:

重载解决的规则是complicated。在这种情况下,func('a','c') 更喜欢int fun(int a, char b) 的原因是因为它暗示了最少的隐式转换序列。查看每个案例:

int fun(int a, int b) 有两个不完全匹配的参数。它需要从charint 的两次晋升。

int fun(int a, char b) 有一个完全匹配和一个从charint 的提升。

int fun(float a, float b) 有两个不完全匹配的参数,需要从 char 转换(比提升更糟糕)到 float

【讨论】:

  • 谢谢。我会接受你的回答,因为它是 cmets 中的第一个!
  • 我也有与此相关的内容:int fun(int a, char b='z'),int fun(float a, float b=0)int fun(long a, long b = 1)。为什么在fun(2e0) 的电话中我得到一个模棱两可的错误?科学记数法是 Double 类型。为什么不能自动转换为浮动?
  • floatdouble 是一种提升,但从doublefloat 是一种转换(它可能必须执行舍入)。所以所有 3 个重载都需要 1 次转换。它与默认参数无关。如果你有一个int fun(double); 并打电话给fun(2.f); 那么它不会抱怨。
  • 扩大范围是促销,缩小范围是转化?
  • @CătălinaSîrbu 这不仅仅是关于宽度,因为 signedunsigned 整数类型。例如,unsigned intsigned int 具有相同的大小,但从一个到另一个是转换。 These 是所有可能的整数提升。 Floating-point promotion 将从 float 变为 double。我不清楚去long double 是如何处理的,但看起来它总是一个转换。
【解决方案2】:

您已经得到答案,正在发生隐式转换。 chars 是特殊的小数字;您可以通过来自&lt;cstdint&gt;coutint 和int8_t 来验证这一点。至于为什么选择2而不是1,这与匹配更多有关。重载 2 与其中一个参数完全匹配,而其他参数都不匹配。而且因为第一个参数可以隐式转换,这是最接近的匹配,因此是编译器选择的重载。

【讨论】:

  • 我已按照 www.cplusplus.com 的教程进行操作。关于为什么进行某些选择的信息很少。说实话,有一个例子。
【解决方案3】:

'c' 是一个char。调用函数 1 需要将其提升为 int。另一方面,对于函数 2,它不必进行转换(这是身份转换)。在对可行函数进行排序以调用重载集时,标准如下所示

[over.match.best]

1 给定这些定义,一个可行的函数 F1 被定义为 如果对于所有参数,则比另一个可行的函数 F2 更好的函数 i,ICSi(F1) 不是比 ICSi(F2) 更差的转换序列,并且 那么

  • 对于某些参数 j,ICSj(F1) 是比 ICSj(F2) 更好的转换序列,或者,

这就是我们这里的情况。与另一个重载相比,第二个参数的隐式转换序列在一个重载中更好。所以它被选中了。

【讨论】:

    【解决方案4】:

    如果您删除 fun(int a, char b),则将调用 fun(int a, int b) 函数。我说这只是作为其他人所说的一个例子。选择 fun(int a, char b) 是因为它比 fun(int a, int b) 匹配得更好。 char 被隐式​​转换为其 ASCII 整数值以匹配函数参数。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-04-19
      • 1970-01-01
      • 2021-03-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多