The name of a function (or the symbol for an operator) can be overloaded; that is, it can be given several uses.
Suppose we need to find the smaller of two values, for several different types of data. We might have functions with prototypes such as:
int Smaller(int A, int B); char Smaller(char A, char B); float Smaller(float A, float B);
The code for each of these is about the same:
if (A < B) return A; else return B;
This is actually legal. Although the three functions all have the same name, the compiler can tell them apart by their lists of arguments:
It does not use the return type for this purpose.
This is a convenience; we could get along without it, most of the time.
With operators, we use overloading all the time and without even thinking about it. For instance, the operator + can be used to add various combinations of numbers:
cout << 3 + 4; // Add int plus int. cout << 3.7 + 8.1; // Add float + float. cout << 7 + 8.2; // Add int + float. cout << 3.9 + 5; // Add float + int.
Likewise the insertion operator << can be used with a wide variety of arguments.
In many cases, much the same effect can be achieved using templates. (See the notes on template functions.)