Nick Nick - 2 months ago 8
C++ Question

Is this correct way to fix ambiguous function call

I have code like this:

#include <cstdio>

void test(size_t const pos){
printf("size_t\n");
}

void test(const void *ptr){
printf("ptr\n");
}

//void test(int const pos){
// printf("int\n");
//}

int main(){
size_t x = 0;

test(x);
test(nullptr);
test(&x);
// test(0);
// some more that fail, but I do not care too much about them:
// test(0U);
// test(0L);
// test(NULL);
}


When I un-comment
test(0);
it does not compile, because the compiler does not know how to convert '0'.

If I introduce 'int' overload, everything compiles again.

Is this correct way to avoid ambiguous function call?

UPDATE

Correct would mean - I want not to call pointer overload, except in case argument is pointer or
nullptr
is passed.

I am aware that current "setup" fails with
0U
,
0L
,
NULL
.

Answer

The literal 0 has type int. If there is a test(int) overload, then this will be called, because no conversion is required. Easy.

If there is no test(int) available, then the compiler will see whether the argument can be converted to either size_t or void* to satisfy the other overloads. A literal 0 can be implicitly converted to either type, and the conversion rules don't tell it to prefer either one, so the result is ambiguous.

In order to specify that you want test(size_t) called, you'll need to explicitly create a 0 of type size_t, i.e.

test(size_t{0});
Comments