这两个重载函数是我写的。
int func(int, int) {
return 1;
}
int func(double, double) {
return 2;
}
当我用明显的两种调用方式调用它们时,即: func(1, 1)
和 func(1.0, 1.0)
,第一个和第二个重载函数分别被调用,而当我尝试调用 func(1, 1.0)
它给了我一个错误,但当我施放了 1
到 long long
,我没有出错,而且第二个重载是被调用的。
#include <iostream>
int main()
{
std::cout << func(1, 1); // outputs 1.
std::cout << func(1.0, 1.0); // outputs 2.
// std::cout << func(1, 1.0); // erroneous.
std::cout << func((long long)1, 1.0); // outputs 2.
}
为什么会出现这种情况呢?起初,我以为是由于某种推广的原因,但我试着用两个float调用第三个重载,但我无法让它被调用,就像调用 func((int)1, 1.0f)
. 我不知道为什么会不一样,我也不知道为什么第二个重载被调用时,一个 long long
被传递了。
从一个重载集中选择哪个函数来调用(也就是 重载解析)取决于(部分地)函数调用的多少个参数必须经过一个叫 隐式转换,以及需要什么样的转换。
与你的例子相关的规则是。
对于每一对可行的函数F1和F2 从第i个参数到第i个参数的隐式转换序列进行排序 以确定哪一个更好。
如果F1的所有参数的隐式转换不比F2的所有参数的隐式转换差,并且......F1至少有一个参数的隐式转换比F2的该参数对应的隐式转换好,则确定F1是比F2更好的函数。
所以给定重载集。
int func(int, int); // #1
int func(double, double); // #2
让我们考虑以下的调用
func(1, 1); // perfect match for #1, so #1 is chosen
func(1., 1.); // perfect match for #2, so #2 is chosen
func(1., 1); // could call #1 by converting 1st argument to int
// (floating-integral conversion)
// could call #2 by converting 2nd argument to double
// (floating-integral conversion)
// error: ambiguous (equal number of conversions needed for both #1 and #2)
func(1ll, 1.); // could call #1 by converting both arguments to ints
// (integral conversion for 1st argument, floating-integral conversion for 2nd argument)
// could call #2 by converting just 1st argument to double
// (floating-integral conversion for 1st argument)
// for the 2nd parameter, #2 is ranked as a better choice,
// since it has a better implicit conversion sequence for #2
// and so #2 is chosen (even though both #1 and #2 are tied for the 1st argument)
现在让我们在其中加入第三个重载。
int func(float, float); // #3
现在当你调用时
func(1, 1.f); // could call #1 by converting 2nd argument to int
// (floating-integral conversion for 2nd argument)
// could call #2 by converting 1st argument to double, and converting 2nd argument to double
// (floating-integral conversion for 1st argument, and floating-point promotion for 2nd argument)
// could call #3 by converting 1st argument to float
// (floating-integral conversion for 2nd argument)
// error: ambiguous (equal number of conversions needed for #1, #2 and #3)