为什么使用不匹配的参数调用重载函数仍然有效
why does calling an overloaded function with arguments that don't match still work
我无法解释为什么第二次调用 (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;
}
您已经得到答案,正在进行隐式转换。 char
s是特殊的小数;您可以通过 cout
int an int8_t
from <cstdint>
来验证这一点。至于为什么选择2而不是1,这与匹配的更多有关。重载 2 与其中一个参数完全匹配,其他 none 匹配。并且因为第一个参数可以隐式转换,这是最接近的匹配,因此是编译器选择的重载。
'c'
是一个 char
。调用函数 1 需要将其提升为 int
。另一方面,对于函数 2,它不必进行转换(这是身份转换)。在对重载集中调用的可行函数进行排序时,标准表示如下
[over.match.best]
1 Given these definitions, a viable function F1 is defined to be
a better function than another viable function F2 if for all arguments
i, ICSi(F1) is not a worse conversion sequence than ICSi(F2), and
then
- for some argument j, ICSj(F1) is a better conversion sequence than ICSj(F2), or,
这就是我们这里的情况。与另一个重载相比,第二个参数的隐式转换序列在一个重载中更好。所以它被选中了。
重载决议的规则是complicated。在这种情况下,func('a','c')
更喜欢 int fun(int a, char b)
的原因是因为它意味着最少的隐式转换序列。查看每个案例:
int fun(int a, int b)
有两个不完全匹配的参数。它需要从 char
到 int
的两次提升。
int fun(int a, char b)
有 1 个完全匹配和 1 个从 char
到 int
的提升。
int fun(float a, float b)
有两个不完全匹配的参数,需要从 char
到 float
.
的转换(比提升更糟糕)
如果删除 fun(int a, char b)
,将调用 fun(int a, int b)
函数。我说这只是作为其他人所说的例子。选择 fun(int a, char b)
是因为它比 fun(int a, int b)
更匹配。 char 隐式转换为其 ASCII 整数值以匹配函数参数。
我无法解释为什么第二次调用 (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;
}
您已经得到答案,正在进行隐式转换。 char
s是特殊的小数;您可以通过 cout
int an int8_t
from <cstdint>
来验证这一点。至于为什么选择2而不是1,这与匹配的更多有关。重载 2 与其中一个参数完全匹配,其他 none 匹配。并且因为第一个参数可以隐式转换,这是最接近的匹配,因此是编译器选择的重载。
'c'
是一个 char
。调用函数 1 需要将其提升为 int
。另一方面,对于函数 2,它不必进行转换(这是身份转换)。在对重载集中调用的可行函数进行排序时,标准表示如下
[over.match.best]
1 Given these definitions, a viable function F1 is defined to be a better function than another viable function F2 if for all arguments i, ICSi(F1) is not a worse conversion sequence than ICSi(F2), and then
- for some argument j, ICSj(F1) is a better conversion sequence than ICSj(F2), or,
这就是我们这里的情况。与另一个重载相比,第二个参数的隐式转换序列在一个重载中更好。所以它被选中了。
重载决议的规则是complicated。在这种情况下,func('a','c')
更喜欢 int fun(int a, char b)
的原因是因为它意味着最少的隐式转换序列。查看每个案例:
int fun(int a, int b)
有两个不完全匹配的参数。它需要从 char
到 int
的两次提升。
int fun(int a, char b)
有 1 个完全匹配和 1 个从 char
到 int
的提升。
int fun(float a, float b)
有两个不完全匹配的参数,需要从 char
到 float
.
如果删除 fun(int a, char b)
,将调用 fun(int a, int b)
函数。我说这只是作为其他人所说的例子。选择 fun(int a, char b)
是因为它比 fun(int a, int b)
更匹配。 char 隐式转换为其 ASCII 整数值以匹配函数参数。