重载,可变函数和bool类型

时间:2016-10-04 15:21:07

标签: c++ c++11

以下程序编译正常并按预期工作。它的输出是:

  

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);
}

2 个答案:

答案 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, 2const char*, ...匹配时,第一个参数的转换序列具有完全匹配等级,第二个到第四个参数的转换序列是省略号转换序列。所以(完全匹配,省略号,省略号,省略号)。

"Test", "xx", 1, 2bool, const char*, ...匹配时,第一个参数的第一个转换序列具有转换排名;第二个是精确匹配,第三个和第四个是省略号转换序列。换句话说,(转换,精确匹配,省略号,省略号)。

完全匹配击败转换;一切都胜过省略号(见[over.ics.rank])。因此,我们在这里有一个所谓的纵横交错的情况,其中一个函数对于一个参数具有更好的转换序列,而另一个函数具有用于另一个参数的更好的转换序列。由于函数比另一个函数更好的必要(但不充分)条件是没有转换序列比其他函数([over.match.best]/1)更差,这两个函数都不比其他