error: call of overloaded ‘function(x)’ is ambiguous | Ambiguity in Function overloading in C++
Last Updated :
12 Jul, 2022
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-
- The number of arguments.
- Order of arguments.
- 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:
- Typecast char to float.
- 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;
}
OutputOverloaded 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;
}
OutputOverloaded 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-
- Typecast float to int.
- 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;
}
OutputOverloaded 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;
}
OutputOverloaded 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;
}
OutputOverloaded function with two int parameter called
21
Overloaded function with one int parameter called
10
Time Complexity: O(1)
Auxiliary Space: O(1)
Similar Reads
C++ Programming Language
C++ is a computer programming language developed by Bjarne Stroustrup as an extension of the C language. It is known for is fast speed, low level memory management and is often taught as first programming language. It provides:Hands-on application of different programming concepts.Similar syntax to
5 min read
SQL Commands | DDL, DQL, DML, DCL and TCL Commands
SQL commands are crucial for managing databases effectively. These commands are divided into categories such as Data Definition Language (DDL), Data Manipulation Language (DML), Data Control Language (DCL), Data Query Language (DQL), and Transaction Control Language (TCL). In this article, we will e
7 min read
TCP/IP Model
The TCP/IP model (Transmission Control Protocol/Internet Protocol) is a four-layer networking framework that enables reliable communication between devices over interconnected networks. It provides a standardized set of protocols for transmitting data across interconnected networks, ensuring efficie
7 min read
Object Oriented Programming in C++
Object Oriented Programming - As the name suggests uses objects in programming. Object-oriented programming aims to implement real-world entities like inheritance, hiding, polymorphism, etc. in programming. The main aim of OOP is to bind together the data and the functions that operate on them so th
5 min read
Basics of Computer Networking
A computer network is a collection of interconnected devices that share resources and information. These devices can include computers, servers, printers, and other hardware. Networks allow for the efficient exchange of data, enabling various applications such as email, file sharing, and internet br
14 min read
Unified Modeling Language (UML) Diagrams
Unified Modeling Language (UML) is a general-purpose modeling language. The main aim of UML is to define a standard way to visualize the way a system has been designed. It is quite similar to blueprints used in other fields of engineering. UML is not a programming language, it is rather a visual lan
14 min read
Waterfall Model - Software Engineering
The Waterfall Model is a Traditional Software Development Methodology. It was first introduced by Winston W. Royce in 1970. It is a linear and sequential approach to software development that consists of several phases. This classical waterfall model is simple and idealistic. It is important because
13 min read
Python Lists
In Python, a list is a built-in dynamic sized array (automatically grows and shrinks). We can store all types of items (including another list) in a list. A list may contain mixed type of items, this is possible because a list mainly stores references at contiguous locations and actual items maybe s
6 min read
Java Programs - Java Programming Examples
In this article, we will learn and prepare for Interviews using Java Programming Examples. From basic Java programs like the Fibonacci series, Prime numbers, Factorial numbers, and Palindrome numbers to advanced Java programs.Java is one of the most popular programming languages today because of its
8 min read
Inheritance in C++
The capability of a class to derive properties and characteristics from another class is called Inheritance. Inheritance is one of the most important features of Object-Oriented Programming in C++. In this article, we will learn about inheritance in C++, its modes and types along with the informatio
10 min read