Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Overloading, variadic functions and bool type

Tags:

c++

c++11

Following program compiles fine and works as expected. Its output is:

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

Now if I change the int parameter of the second Bar function into bool and foo1.Bar(1, "xx", "xx", 2, 2); into foo1.Bar(true, "xx", "xx", 2, 2);, then the following line won't compile and I get the error: 'Foo::Bar': 2 overloads have similar conversions:

  foo1.Bar("Test", "xx", 1, 2);

The whole program that doesn't compile:

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

I don't understand why there is an ambiguity in the second case.

EDIT

But if pointers implicitly convert to bool, why does following compile ?

#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);
}
like image 305
Jabberwocky Avatar asked Oct 04 '16 15:10

Jabberwocky


1 Answers

When you match "Test", "xx", 1, 2 against const char*, ..., the conversion sequence for the first argument has exact match rank, the second through fourth one are ellipsis conversion sequences. So (exact match, ellipsis, ellipsis, ellipsis).

When you match "Test", "xx", 1, 2 against bool, const char*, ..., the first conversion sequence for the first argument has conversion rank; the second is an exact match, the third and fourth are ellipsis conversion sequences. In other words, (conversion, exact match, ellipsis, ellipsis).

Exact match beats conversion; everything beats ellipsis (see [over.ics.rank]). Thus we have a so-called criss-cross situation here where one function has a better conversion sequence for one argument and the other function has a better conversion sequence for another argument. Since a necessary (but not sufficient) condition for a function to be better than another function is that none of the conversion sequences are worse than those of the other function ([over.match.best]/1), neither of those two functions is better than the other.

like image 108
T.C. Avatar answered Oct 07 '22 14:10

T.C.