函数重载变得模棱两可
Function overloading getting ambiguous
重载函数时:
void add(int a)
{
a=7;
cout<<"int";
}
void add(double a)
{
a=8.4;
cout<<"double";
}
void add(int *b)
{
*b=4;
cout<<"pointer";
}
int main()
{
char i='a'; //char
add(i);
return 0;
}
输出:int
尽管没有以 char 数据类型作为参数的函数,但它工作正常。
但是当编译成下面的代码时:
void add(char a)
{
a='a';
cout<<"int";
}
void add(double a)
{
a=8.4;
cout<<"double";
}
void add(int *b)
{
*b=4;
cout<<"pointer";
}
int main()
{
int i=4; //int
add(i);
return 0;
}
给出错误(编译器 gcc):
cpp|21|error: call of overloaded 'add(int&)' is ambiguous
这背后的逻辑是什么?以及如何跟踪此类代码的控制传递或输出?
原因是当没有精确的类型匹配时,编译器会寻找最接近的匹配。
这就是为什么当它是 - char i='a';
最接近的匹配是 void add(int a)
但是当它是 int i=4; //int
时,现在有 2 个匹配项。所以这就是它模棱两可的原因。
A char
适合 int
而不会溢出或丢失精度,这解释了第一个代码。
但是 int
不适合 char
(溢出)、double
(缺乏精度)或 int*
(不兼容类型)。
这个例子归结为整数提升和整数转换的区别。简而言之,促销是:
A prvalue of an integer type other than bool, char16_t, char32_t, or wchar_t whose integer conversion
rank (4.13) is less than the rank of int can be converted to a prvalue of type int if int can represent all
the values of the source type; otherwise, the source prvalue can be converted to a prvalue of type unsigned int. [...] These conversions are called integral promotions.
而整数转换更通用:
A prvalue of an integer type can be converted to a prvalue of another integer type. [...] The conversions allowed as integral promotions are excluded from the set of integral conversions.
为了重载解析,整数提升是比整数转换更好的转换。
在第一个例子中,我们有:
add(int ); // (1)
add(double ); // (2)
add(int* ); // (3)
并且正在用 char
呼叫。只有前两个是可行的,都涉及转换。 (1)涉及一个Integer Promotion,其中有rank Promotion。 (2)涉及到一个浮点数转换,有秩转换。 Promotion 的排名高于 Conversion,因此 (1) 无疑是首选。
现在,在第二个例子中,我们有:
add(char ); // (1)
add(double ); // (2)
add(int* ); // (3)
并且正在用 int
呼叫。再一次,只有前两个是可行的,并且都涉及转换。 (1) 这次涉及一个积分转换(因为char
的秩低于int
)和 (2) 仍然涉及一个浮点积分转换,两者具有相同的秩:转换。由于我们有两个排名相同的转化,因此没有 "best" 转化,因此没有最佳可行候选者。因此,我们有一个模棱两可的决议。
重载函数时:
void add(int a)
{
a=7;
cout<<"int";
}
void add(double a)
{
a=8.4;
cout<<"double";
}
void add(int *b)
{
*b=4;
cout<<"pointer";
}
int main()
{
char i='a'; //char
add(i);
return 0;
}
输出:int
尽管没有以 char 数据类型作为参数的函数,但它工作正常。
但是当编译成下面的代码时:
void add(char a)
{
a='a';
cout<<"int";
}
void add(double a)
{
a=8.4;
cout<<"double";
}
void add(int *b)
{
*b=4;
cout<<"pointer";
}
int main()
{
int i=4; //int
add(i);
return 0;
}
给出错误(编译器 gcc):
cpp|21|error: call of overloaded 'add(int&)' is ambiguous
这背后的逻辑是什么?以及如何跟踪此类代码的控制传递或输出?
原因是当没有精确的类型匹配时,编译器会寻找最接近的匹配。
这就是为什么当它是 - char i='a';
最接近的匹配是 void add(int a)
但是当它是 int i=4; //int
时,现在有 2 个匹配项。所以这就是它模棱两可的原因。
A char
适合 int
而不会溢出或丢失精度,这解释了第一个代码。
但是 int
不适合 char
(溢出)、double
(缺乏精度)或 int*
(不兼容类型)。
这个例子归结为整数提升和整数转换的区别。简而言之,促销是:
A prvalue of an integer type other than bool, char16_t, char32_t, or wchar_t whose integer conversion rank (4.13) is less than the rank of int can be converted to a prvalue of type int if int can represent all the values of the source type; otherwise, the source prvalue can be converted to a prvalue of type unsigned int. [...] These conversions are called integral promotions.
而整数转换更通用:
A prvalue of an integer type can be converted to a prvalue of another integer type. [...] The conversions allowed as integral promotions are excluded from the set of integral conversions.
为了重载解析,整数提升是比整数转换更好的转换。
在第一个例子中,我们有:
add(int ); // (1)
add(double ); // (2)
add(int* ); // (3)
并且正在用 char
呼叫。只有前两个是可行的,都涉及转换。 (1)涉及一个Integer Promotion,其中有rank Promotion。 (2)涉及到一个浮点数转换,有秩转换。 Promotion 的排名高于 Conversion,因此 (1) 无疑是首选。
现在,在第二个例子中,我们有:
add(char ); // (1)
add(double ); // (2)
add(int* ); // (3)
并且正在用 int
呼叫。再一次,只有前两个是可行的,并且都涉及转换。 (1) 这次涉及一个积分转换(因为char
的秩低于int
)和 (2) 仍然涉及一个浮点积分转换,两者具有相同的秩:转换。由于我们有两个排名相同的转化,因此没有 "best" 转化,因此没有最佳可行候选者。因此,我们有一个模棱两可的决议。