Jaskamal Kainth

C++ Notes

Ill Formed function call due to Ambiguous function overloading

#include <iostream>

void foo(const char* str) // Function 1
{
    std::cout << "F1 = " << str << std::endl;
}
void foo(short n) // Function 2
{
    std::cout << "F2 = " << n << std::endl;
}
int main()
{
    foo("randomString"); // Function 1 is called
    foo(1); // Function 2 is called

    foo(0); 
    // In this case 0 can be implictly treated as a "nullptr" or an integer
    // so with 1 implicit conversion sequence compiler can deduce either of the Function 1 or 2
    // Hence it is an ill-formed function call and a compilation error.
    return 0;
}

Compilation Error:

    ill-formed-function-call.cpp:16:5: error: call to 'foo' is ambiguous
        foo(0); 
        ^~~
    ill-formed-function-call.cpp:3:6: note: candidate function
    void foo(const char* str) // Function 1
        ^
    ill-formed-function-call.cpp:7:6: note: candidate function
    void foo(short n) // Function 2
        ^
    1 error generated.
  • In the above code, both the function foo() are viable and for a compiler to choose, one of them has to have a better conversion sequence but since 0 is of type int and also a nullptr constant, in both cases we have a single conversion and hence no function is better than the other hence ill-formed.
  • If the function defination had foo(int) then the compiler can treat 0 as integer without any implicit conversion and hence no error.
  • Similarly if we pass foo(0L) and we have a definition like foo(long n).

    Note: nullptr constant is an integer literal with value 0.