A call to an overloaded function can be ambiguous when the compiler cannot determine which version of the function to invoke because multiple overloaded functions are equally good matches for the given arguments. This ambiguity typically arises due to automatic type conversions or promotions that make more than one function candidate viable, but none clearly better than the others.
How Ambiguity Occurs
- Automatic Type Conversion: When the argument types in a function call do not exactly match any overloaded function, the compiler tries to convert the arguments to match one of the overloaded versions. If multiple conversions are possible and lead to different overloaded functions, the call becomes ambiguous. For example, a
char
argument might be convertible to bothfloat
anddouble
, and if overloaded functions exist for both types, the compiler cannot decide which to call
- Numeric Promotions and Conversions: Consider overloaded functions
foo(int)
andfoo(double)
. Callingfoo(5L)
(where5L
is along
) can be ambiguous iflong
can be converted to bothint
anddouble
with no clear preference, causing the compiler to report an ambiguous call error
- Default Arguments: Overloaded functions with default parameters can cause ambiguity if a call matches multiple overloads with different numbers of parameters due to default values. For example, calling
sum(100)
might be ambiguous if there aresum(int)
andsum(int, int = 0)
overloads
- Multiple Candidate Sets: When the compiler builds candidate sets of functions for each argument and finds no unique best match because the intersection of candidate sets is empty, ambiguity arises. For instance, calling
Add(3, 6)
where multiple overloads acceptFraction
andlong
in different argument orders can lead to ambiguity
Example
cpp
void display(int);
void display(long);
display(3.3f); // float argument
Here, 3.3f
(float) can be converted to both int
and long
, but neither
conversion is better than the other, so the call is ambiguous
How to Resolve Ambiguity
- Explicit Typecasting: Cast the argument to the desired type to guide the compiler to the correct overload.
- Add an Exact Match Overload: Define a new overloaded function that exactly matches the argument type.
- Remove or Modify Overloads: Eliminate or change overloads that cause ambiguity, such as removing default parameters or changing argument types.
- Use Literal Suffixes: For literals, use suffixes to specify the exact type, e.g.,
0u
forunsigned int
to avoid ambiguity
In summary, a call to an overloaded function is ambiguous when automatic conversions or default arguments make multiple overloads equally valid candidates, preventing the compiler from selecting a single best match. This results in a compile-time error until the ambiguity is resolved by explicit casting, adding precise overloads, or modifying existing ones