Open In App

error: call of overloaded ‘function(x)’ is ambiguous | Ambiguity in Function overloading in C++

Last Updated : 12 Jul, 2022
Improve
Improve
Like Article
Like
Save
Share
Report

Pre-requisite: Function Overloading in C++

Function overloading is a feature of object-oriented programming where two or more functions can have the same name but different parameters. When a function name is overloaded with different jobs it is called Function Overloading. Two or more functions are said to be overloaded if they differ in any of the following-

  1. The number of arguments.
  2. Order of arguments.
  3. Type of arguments.

In Function overloading, sometimes a situation can occur when the compiler is unable to choose between two correctly overloaded functions. This situation is said to be ambiguous. 

Ambiguous statements are error-generating statements and the programs containing ambiguity will not compile. Automatic type conversions are the main cause of ambiguity. In C++, the type of argument that is used to call the function is converted into the type of parameters defined by the function. 

Let’s understand ambiguity through a few examples.

Call of overloaded function is ambiguous

Example 1: Call of overloaded ‘test(char)’ is ambiguous

How this ambiguity occurs:
Below is the C++ program to demonstrate the ambiguity.

C++




// C++ program to implement
// the above approach
#include <iostream>
using namespace std;
 
// Overloaded Function with
// float type parameter
void test(float f)
{
    cout << "Overloaded Function with float "
         << "parameter being called";
}
 
// Overloaded Function with
// double type parameter
void test(double d)
{
    cout << "Overloaded Function with double "
         << "parameter being called";
}
 
// Driver code
int main()
{
    // Overloaded Function called
    // with char type value
    test('a');
 
    return 0;
}


Output:

prog.cpp: In function ‘int main()’:

prog.cpp:25:11: error: call of overloaded ‘test(char)’ is ambiguous

  test(‘a’);

          ^

prog.cpp:8:6: note: candidate: void test(float)

void test(float f)  

     ^

prog.cpp:15:6: note: candidate: void test(double)

void test(double d)  

     ^

Why ambiguity occurs:

 When there is no exact type match, the compiler looks for the closest match. The closest match for “test(‘a’);” will be “void test(int a)”, since it is not present, void test(double d) and void (float f)will cause ambiguity. Both are valid conversions. This confusion causes an error message to be displayed and prevents the program from compiling.

Note:
According to the C language specification, any integer type shorter than int, for example, bool, char, short are implicitly converted to int.

A char fits into an int without overflowing or losing precision, which explains the first code. But an int doesn’t fit into a char (overflow), double (lack of precision), or int* (incompatible type).

How to resolve ambiguity:

There are two ways to resolve this ambiguity:

  1. Typecast char to float.
  2. Remove either one of the ambiguity generating functions float or double and add overloaded function with an int type parameter.

Solution 1: Typecast char to float

Below is the C++ program to demonstrate how typecasting char to float resolves the issue.

C++




// C++ program to implement
// the above approach
#include <iostream>
using namespace std;
 
// Overloaded Function with
// float type parameter
void test(float f)
{
    cout << "Overloaded Function with float "
         << "parameter being called";
}
 
// Overloaded Function with
// double type parameter
void test(double d)
{
    cout << "Overloaded Function with double "
         << "parameter being called";
}
 
// Driver code
int main()
{
    // Overloaded Function called
    // with char type value
    // typecasted to float
    test((float)('a'));
 
    return 0;
}


Output

Overloaded Function with float parameter being called

Solution 2: Remove either one of the ambiguity generating functions float or double and add overloaded function with an int type parameter.

Below is the C++ program to demonstrate how adding an overloading function with an int type parameter can resolve the ambiguity in the above code.

C++




// C++ program to implement
// the above approach
#include <iostream>
using namespace std;
 
// Overloaded function with
// int type parameter
void test(int f)
{
    cout << "Overloaded Function with "
         << "int type parameter called";
}
 
// Overloaded function with
// double type parameter
void test(double d)
{
    cout << "Overloaded Function with "
         << "double type parameter called";
}
 
// Driver code
int main()
{
    // Overloaded Function called
    // with char type value
    test('a');
    return 0;
}


Output

Overloaded Function with int type parameter called

Example 2: Call of overloaded ‘test(float)’ is ambiguous

How this ambiguity occurs:
Below is the C++ program to demonstrate what will happen in the scenario when the type of float value is used to call the overloaded function and there is no function with the float or double parameters.

C++




// C++ program to implement
// the above approach
#include <iostream>
using namespace std;
 
// Overloaded function with
// int type parameter
void test(int f)
{
    cout << "Overloaded Function with "
         << "int type parameter called";
}
 
// Overloaded function with
// long type parameter
void test(long l)
{
    cout << "Overloaded Function with "
         << "long type parameter called";
}
 
// Driver code
int main()
{
    // Overloaded Function called
    // with float type value
    test(2.5f);
    return 0;
}


Output:

prog.cpp: In function ‘int main()’:

prog.cpp:25:12: error: call of overloaded ‘test(float)’ is ambiguous

  test(2.5f);

           ^

prog.cpp:8:6: note: candidate: void test(int)

void test(int f)  

     ^

prog.cpp:15:6: note: candidate: void test(long int)

void test(long d)  

     ^

Why ambiguity occurs:
The above code will throw an error because the test(2.5f) function call will look for float function if not present it is only promoted to double, but there is no function definition with double or float type of parameter.

Unless explicitly specified all floating-point literals are automatically of type double in C++. In this ambiguity, the variable of a float type is implicitly converted to double type and if there is no overloaded function of float or double type and the function is called with a float value then the program will throw an error.

Note:
The float is converted to double under the following situations:

  • The float is an argument to a function call, corresponding to a parameter type double in a function prototype.
  • A binary operator has double and float as two argument types.
  • A conditional operator has double and float as a second and third operand.
  • The float value is cast to double.
  • The float value is assigned to double.

How to resolve ambiguity:

There are two ways to resolve the ambiguity-

  1. Typecast float to int.
  2. Remove either one of the ambiguity generating functions int or long and add overloaded function with a double type parameter.

Solution 1: Typecast float to int

Below is the C++ program to demonstrate how typecasting float to int resolves the issue.

C++




// C++ program to implement
// the above approach
#include <iostream>
using namespace std;
 
// Overloaded function with
// int type parameter
void test(int f)
{
    cout << "Overloaded Function with "
         << "int type parameter called";
}
 
// Overloaded function with
// long type parameter
void test(long l)
{
    cout << "Overloaded Function with "
         << "long type parameter called";
}
 
// Driver code
int main()
{
    // Overloaded Function called
    // with float type value
    test((int)(2.5f));
    return 0;
}


Output

Overloaded Function with int type parameter called

Solution 2: Remove either one of the ambiguity generating functions int or long and add overloaded function with a double type parameter.

Below is the C++ program to demonstrate how to resolve this ambiguity by adding an overloaded function with double type parameters.

C++




// C++ program to implement
// the above approach
#include <iostream>
using namespace std;
 
// Overloaded function with
// int type parameter
void test(double d)
{
    cout << "Overloaded Function with "
         << "double type parameter called";
}
 
// Overloaded function with
// long type parameter
void test(long l)
{
    cout << "Overloaded Function with "
         << "long type parameter called";
}
 
// Driver code
int main()
{
    // Overloaded Function called
    // with float type value
    test(2.5f);
    return 0;
}


Output

Overloaded Function with double type parameter called

Call of overloaded function with different number of arguments

Redefinition of ‘void test(int, int) function:
Let’s look at another ambiguity scenario where ambiguity occurs when it is two-parameter and one of the parameters has a default value set.

C++




// C++ program to implement
// the above approach
#include <iostream>
using namespace std;
 
// Overloaded Function with
// one int type parameter
void test(int i)
{
    cout << "Overloaded function with "
         << "one int parameter called " << endl;
    cout << i;
}
 
// Overloaded Functionwith
// two int type parameter
void test(int i, int j = 5)
{
    int sum;
    sum = i + j;
 
    cout << "Overloaded function with "
         << "two int parameter called " << endl;
    cout << sum;
}
 
// Driver code
int main()
{
    // Overloaded Function called
    // with two int values
    // Unambiguous call
    test(10, 11);
 
    // Overloaded Function called
    // with one int value
    // Ambiguous call
    test(10);
 
    return 0;
}


Output:

prog.cpp: In function ‘void test(int, int)’:

prog.cpp:17:6: error: redefinition of ‘void test(int, int)’

void test(int i, int j = 5)  

     ^

prog.cpp:8:6: note: ‘void test(int, int)’ previously defined here

void test(int i, int j)  

     ^

prog.cpp: In function ‘int main()’:

prog.cpp:35:10: error: too few arguments to function ‘void test(int, int)’

  test(10);

         ^

prog.cpp:8:6: note: declared here

void test(int i, int j)  

     ^

Why ambiguity occurs:

Here, in the unambiguous call statement test(10, 11) two arguments are specified, therefore there is no ambiguity. In the ambiguous call statement test(10), the compiler gets confused about whether to call the first function test() which takes one argument or to call the second test() function with two arguments out of which one is the default. This causes the program to throw an error.

How to resolve the ambiguity:

One solution to resolve the ambiguity is to remove the default value from the overloaded function with two int parameters. Below is the C++ program to demonstrate the above approach-

C++




// C++ program to implement
// the above approach
#include <iostream>
using namespace std;
 
// Overloaded Function with
// one int type parameter
void test(int i)
{
    cout << "Overloaded function with "
         << "one int parameter called " << endl;
    cout << i << endl;
}
 
// Overloaded Functionwith
// two int type parameter
void test(int i, int j)
{
    int sum;
    sum = i + j;
 
    cout << "Overloaded function with "
         << "two int parameter called " << endl;
    cout << sum << endl;
}
 
// Driver code
int main()
{
    // Overloaded Function called
    // with two int values
    // Unambiguous call
    test(10, 11);
 
    // Overloaded Function called
    // with one int value
    // Ambiguous call
    test(10);
 
    return 0;
}


Output

Overloaded function with two int parameter called 
21
Overloaded function with one int parameter called 
10

Time Complexity: O(1)

Auxiliary Space: O(1)



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads