Function Overloading

In C, a function is uniquely identified by its name. So code such as this #include <stdio.h> void PrintGreeting ( void ); void PrintGreeting (char *message); int main ( ) { PrintGreeting( ); PrintGreeting ("Hello World\n"); return 0; } void PrintGreeting ( void ) { printf ("Hi World\n"); } void PrintGreeting (char *msg) { printf ("%s", msg); } results in compiler errors like this CFunctions.c:5: conflicting types for `PrintGreeting' CFunctions.c:4: previous declaration of `PrintGreeting' CFunctions.c: In function `main': CFunctions.c:9: too few arguments to function `PrintGreeting' CFunctions.c: At top level: CFunctions.c:16: conflicting types for `PrintGreeting' CFunctions.c:5: previous declaration of `PrintGreeting' CFunctions.c:21: conflicting types for `PrintGreeting' CFunctions.c:16: previous declaration of `PrintGreeting' This restriction requires you to create different names for functions which perform virtually identical tasks.

In C++, functions are unqiuely identified by their name AND their formal parameters (number and type). This combination of information is called the function signature. This combination allows you to have two or more functions with the same name if they have different parameters. This is known as function overloading. (Note that a function's return type is NOT part of it's signature.)

When the code above is modified to be C++ code

#include <iostream> using namespace std; void PrintGreeting ( ); void PrintGreeting (char *message); int main ( ) { PrintGreeting( ); PrintGreeting ("Hello World\n"); return 0; } void PrintGreeting ( ) { cout << "Hi World\n"; } void PrintGreeting (char *msg) { cout << msg; } It compiles without errors and creates an executable. linuxserver1[140] g++ -ansi -Wall PrintGreeting.cpp linuxserver1[141] a.out Hi World Hello World

Overloading Pitfalls and Function Resolution

As we learned in CMSC 201, when only one version of a function exists, the compiler will use automatic type conversion (aka promotion) in order to call that function when the argument type in the function call is not an exact match for the formal parameter. For example, given the function // mpg - returns miles per gallon double mpg( double miles, double gallons) { return miles / gallons; } and the function call cout << mpg( 45, 2 ) << endl; the compiler will automatically convert (aka promote) the integers 45 and 2 to be of type double so that the function mpg( ) can be called. This is a good thing and exactly what we want to happen. That's why all the C language math functions (for example) have formal parameters of type double.

With function overloading, we have to be careful not to give the compiler too many choices. The interaction of overloading and automatic type conversion can be confusing to you and the compiler. Consider the (ill concieved) overloaded function f( ) below

void f( int n, double m); void f( double n, int m); and the function call f (45, 2); The compiler now has too many options. It can
  1. Promote the integer 2 to a double and call f(int n, double m)
  2. Promote the integer 45 to double and call f(double n, int m)
Given these ambiguous choices, the compiler will generate an error message (as we saw with sqrt( ) and pow( )).

So, how do we solve this problem? How does the compiler decide which overloaded function to call?.
The rules for resolving overloaded function calls are

  1. Exact Match -- if the number and types of the arguments in the function call exactly match a function definition (with no automatic promotion), then that is the function which is called.
  2. Match with Promotion -- if there is no exact match but there is a match using automatic promotion, then that match is used
A compiler error is generated when
  1. Two exact matches are found
    --- OR ---
  2. No exact matches are found, but two or more matches are found using automatic type promotion
Either of these conditions lead to the error "call of overloaded 'function name' is ambiguous".

So, how do we resolve the problem with the ill-concieved function f( ) above?


Last Modified: Monday, 28-Aug-2006 10:15:59 EDT