Overload resolution (C++ only)
The process of selecting the most appropriate overloaded function or operator is called overload resolution.
Suppose that f
is an overloaded function name. When
you call the overloaded function f()
, the compiler creates
a set of candidate functions. This set of functions includes
all of the functions named f
that can be accessed from
the point where you called f()
. The compiler may include
as a candidate function an alternative representation of one of those
accessible functions named f
to facilitate overload resolution.
After creating a set of candidate functions, the compiler creates
a set of viable functions. This set of functions
is a subset of the candidate functions. The number of parameters of
each viable function agrees with the number of arguments you used
to call f()
.
The compiler chooses the best viable function, the function declaration
that the C++ runtime environment will use when you call f()
,
from the set of viable functions. The compiler does this by implicit conversion sequences. An implicit conversion
sequence is the sequence of conversions required to convert an argument
in a function call to the type of the corresponding parameter in a
function declaration. The implicit conversion sequences are ranked;
some implicit conversion sequences are better than others. The best
viable function is the one whose parameters all have either better
or equal-ranked implicit conversion sequences than all of the other
viable functions. The compiler will not allow a program in which the
compiler was able to find more than one best viable function. Implicit
conversion sequences are described in more detail in Implicit conversion sequences (C++ only).
f
is not allowed because void f(int [])
has
already been defined.
void f(int a[*]) {}
void f(int a[5]) {} // illegal
However, array dimensions other
than the leftmost in a variable length array do differentiate candidate
functions when the variable length array is a function parameter.
For example, the overload set for function f
might comprise
the following:
void f(int a[][5]) {}
void f(int a[][4]) {}
void f(int a[][g]) {} // assume g is a global int
but cannot
include
void f(int a[][g2]) {} // illegal, assuming g2 is a global int
because
having candidate functions with second-level array dimensions g
and g2
creates
ambiguity about which function f
should be called: neither g
nor g2
is
known at compile time.f()
matches with f(void*)
:
void f(int) { };
void f(void*) { };
int main() {
f(0xaabb); // matches f(int);
f((void*) 0xaabb); // matches f(void*)
}