Functions can be overloaded so long as each overloaded function can be differentiated by the compiler. If an overloaded function can not be differentiated, a compile error will result.
Introduction to function overloading
Function overloading allows us to create multiple functions with the same name, so long as each identically named function has different parameter types (or the functions can be otherwise differentiated).
Function overload differentiation
How overloaded functions are differentiated
Function property | Used for differentiation | Notes |
---|---|---|
Number of parameters | Yes | |
Type of parameters | Yes | Excludes typedefs, type aliases, and const qualifier on value parameters. Includes ellipses. |
Return type | No |
- Ellipses:
1
2void func(int, ...);
void func(double, ...); // may not differentiatiable
Overloading based on number of parameters
1 | int add(int x, int y) |
Overloading based on type of parameters
1 | int add(int x, int y); // integer version |
Because type aliases (or typedefs) are not distinct types, overloaded functions using type aliases are not distinct from overloads using the aliased type.
For parameters passed by value, the const qualifier is also not considered (But for parameters passed by pointer, const qualifier can be differentiated). Therefore, the following functions are not considered to be differentiated:
1 | void print(int); |
The return type of a function is not considered for differentiation
A function’s return type is not considered when differentiating overloaded functions.
1 | int getRandomValue(); |
Type signature
A function’s type signature (generally called a signature) is defined as the parts of the function header that are used for differentiation of the function.
Function overload resolution and ambiguous matches
The process of matching function calls to a specific overloaded function is called overload resolution.
Resolving overloaded function calls
Three possible outcomes:
- No matching functions were found. The compiler moves to the next step in the sequence.
- A single matching function was found. This function is considered to be the best match. The matching process is now complete, and subsequent steps are not executed.
- More than one matching function was found. The compiler will issue an ambiguous match compile error. We’ll discuss this case further in a bit.
If the compiler reaches the end of the entire sequence without finding a match, it will generate a compile error that no matching overloaded function could be found for the function call.
The argument matching sequence
- Step 1 : The compiler tries to find an exact match
- First, the compiler will see if there is an overloaded function where the type of the arguments in the function call exactly matches the type of the parameters in the overloaded functions.
- Second, the compiler will apply a number of trivial conversions to the arguments in the function call. The trivial conversions are a set of specific conversion rules that will modify types (without modifying the value) for purposes of finding a match. These include:
- lvalue to rvalue conversions
- qualification conversions (e.g. non-const to const)
- non-reference to reference conversions
- Step 2: If no exact match is found, the compiler tries to find a match by applying numeric promotion to the argument(s).
- Step 3: If no match is found via numeric promotion, the compiler tries to find a match by applying numeric conversions