How to resolve ambiguity of call to overloaded function with literal 0 and pointer

mfya picture mfya · Jan 6, 2011 · Viewed 6.9k times · Source

I'm pretty sure this must have been here already, but I didn't find much information on how to solve this kind of problem (without casting on the call):

Given two overloads, I want that a call with function with a literal 0 always calls the unsigned int version:

void func( unsigned int ) {
    cout << "unsigned int" << endl;
}

void func( void * ) {
    cout << "void *" << endl;
}

func( 0 ); // error: ambiguous call

I understand why this happens, but I don't want to write func( 0u ) or even func( static_cast(0) ) all the time. So my questions are:

1) Is there a recommended way to do this in general?

2) Is there any problem with doing it the following way and what is the reason that this to works?

void func( unsigned int ) {
    cout << "unsigned int" << endl;
}

template <typename T>
void func( T * ) {
    static_assert( std::is_same<T, void>::value, "only void pointers allowed" );
    cout << "void *" << endl;
}

func( 0 ); // calls func( unsigned int )!

Answer

EboMike picture EboMike · Jan 6, 2011

What you're doing in 2) works and is probably the better way to do it.

In situations where you don't want to change the functions, you can do an explicit cast to give the compiler a hint:

func((void *) 0);
func((unsigned int) 0);