以下程序编译正常并按预期工作。它的输出是:
1
2
#include <stdio.h>
class Foo
{
public:
void Bar(const char* b, ...) { printf("1\n"); };
void Bar(int a, const char* b, ...) { printf("2\n"); };
};
int main()
{
Foo foo1;
foo1.Bar("Test", "xx", 1, 2);
foo1.Bar(1, "xx", "xx", 2, 2);
}
现在,如果我将第二个int
函数的Bar
参数更改为bool
并将foo1.Bar(1, "xx", "xx", 2, 2);
更改为foo1.Bar(true, "xx", "xx", 2, 2);
,则以下行将无法编译我收到错误:'Foo::Bar': 2 overloads have similar conversions
:
foo1.Bar("Test", "xx", 1, 2);
整个无法编译的程序:
#include <stdio.h>
class Foo
{
public:
void Bar(const char* b, ...) { printf("1\n"); };
void Bar(bool a, const char* b, ...) { printf("2\n"); };
};
int main()
{
Foo foo1;
foo1.Bar("Test", "xx", 1, 2); // error: 'Foo::Bar': 2 overloads have similar conversions
foo1.Bar(true, "xx", "xx", 2, 2);
}
我不明白为什么第二种情况会有歧义。
修改
但是如果指针隐式转换为bool
,为什么要进行编译?
#include <stdio.h>
class Foo
{
public:
void Bar(const char* b) { printf("1\n"); };
void Bar(bool a) { printf("2\n"); };
};
int main()
{
Foo foo1;
foo1.Bar("Test");
foo1.Bar(true);
}
答案 0 :(得分:5)
这很好:
#include <stdio.h>
class Foo
{
public:
void Bar(const char* b, ...) { printf("1\n"); };
void Bar(bool a, ...) { printf("2\n"); };
};
int main()
{
Foo foo;
foo.Bar("Test");
}
这不太好:
#include <stdio.h>
class Foo
{
public:
void Bar(const char* b, ...) { printf("1\n"); };
void Bar(bool a, char another, ...) { printf("2\n"); };
};
int main()
{
Foo foo;
foo.Bar("Test", 'c'); // Ambiguous!
}
在第一种情况下,Bar()的第一个版本显然更好。但在第二种情况下,它不再那么清楚,因为虽然第一个版本与参数1的匹配更好,但第二个版本与参数2的匹配更好。
剩下的问题是:为什么使用'int'代替'bool'可以避免歧义?答案是指针可能会隐式转换为bool而不是int。
答案 1 :(得分:5)
当"Test", "xx", 1, 2
与const char*, ...
匹配时,第一个参数的转换序列具有完全匹配等级,第二个到第四个参数的转换序列是省略号转换序列。所以(完全匹配,省略号,省略号,省略号)。
当"Test", "xx", 1, 2
与bool, const char*, ...
匹配时,第一个参数的第一个转换序列具有转换排名;第二个是精确匹配,第三个和第四个是省略号转换序列。换句话说,(转换,精确匹配,省略号,省略号)。
完全匹配击败转换;一切都胜过省略号(见[over.ics.rank])。因此,我们在这里有一个所谓的纵横交错的情况,其中一个函数对于一个参数具有更好的转换序列,而另一个函数具有用于另一个参数的更好的转换序列。由于函数比另一个函数更好的必要(但不充分)条件是没有转换序列比其他函数([over.match.best]/1)更差,这两个函数都不比其他