Search

8.9 — Introduction to function overloading

Consider the following function:

This trivial function adds two integers and returns an integer result. However, what if we also want a function that can add two floating point numbers? This add() function is not suitable, as any floating point parameters would be converted to integers, causing the floating point arguments to lose their fractional values.

One way to work around this issue is to define multiple functions with slightly different names:

However, for best effect, this requires that you define a consistent function naming standard for similar functions that have parameters of different types, remember the names of these functions, and actually call the correct one.

And then what happens when we want to have a similar function that adds 3 integers instead of 2? Managing unique names for each function quickly becomes burdensome.

Introduction to function overloading

Fortunately, C++ has an elegant solution to handle such cases. Function overloading allows us to create multiple functions with the same name, so long as each identically named function has different parameters (or the functions can be otherwise differentiated). Each function sharing a name (in the same scope) is called an overloaded function (sometimes called an overload for short).

To overload our add() function, we can simply declare another add() function that takes double parameters:

We now have two versions of add() in the same scope:

The above program will compile. Although you might expect these functions to result in a naming conflict, that is not the case here. Because the parameter types of these functions differ, the compiler is able to differentiate these functions, and will treat them as separate functions that just happen to share a name.

Key insight

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.

Related content

Because operators in C++ are just functions, operators can also be overloaded. We’ll discuss this in %Failed chapter reference, id overloading%.

Introduction to overload resolution

Additionally, when a function call is made to function that has been overloaded, the compiler will try to match the function call to the appropriate overload based on the arguments used in the function call. This is called overload resolution.

Here’s a simple example demonstrating this:

The above program compiles and produces the result:

3
4.6

When we provide integer arguments in the call to add(1, 2), the compiler will determine that we’re trying to call add(int, int). And when we provide floating point arguments in the call to add(1.2, 3.4), the compiler will determine that we’re trying to call add(double, double).

Making it compile

In order for program using overloaded functions to compile, two things have to be true:

  1. Each overloaded function has to be differentiated from the others. We discuss how functions can be differentiated in lesson 8.10 -- Function overload differentiation.
  2. Each call to an overloaded function has to resolve to an overloaded function. We discuss how the compiler matches function calls to overloaded functions in lesson 8.11 -- Overloaded function resolution.

If an overloaded function is not differentiated, or if a function call to an overloaded function can not be resolved to an overloaded function, then a compile error will result.

In the next lesson, we’ll explore how overloaded functions can be differentiated from each other. Then, in the following lesson, we’ll explore how the compiler resolves function calls to overloaded functions.

Conclusion

Function overloading provides a great way to reduce the complexity of your program by reducing the number of function names you need to remember. It can and should be used liberally.

Best practice

Use function overloading to make your program simpler.


8.10 -- Function overload differentiation
Index
8.8 -- Type deduction for functions

34 comments to 8.9 — Introduction to function overloading

  • shini

    what are the rules to be followed in function overloading?

  • developer

    i was expecting name mangling here

  • Jyoti

    Hi Alex..
    I have heard that "Avoid overloading function where one takes integral type argument and other takes pointer"
    What could be the reason?

    Thanx

  • Matt

    This really confuses me here.

    typedef char *string;
    void Print(string szValue);
    void Print(char *szValue);

    What exactly does the asterisk do in this situation? The closest thing I can relate it to is the pointer stuff but it's not pointing to any address here. I tried reviewing the previous lessons again but I still don't get it.

  • Above it says:

    There are two ways to resolve ambiguous matches:

    1) Define a new overloaded function that takes parameters of exactly the type you are trying to call the function with.

    2) Explicitly cast the ambiguous parameter(s) to the type of the function you want to call.

    I would propose a third way:

    3) Simply give each and every function a unique name.

    In other words, avoid problems with overloading by not using overloading. At least as long as you don't see considerate advantages with using overloading.

    PS: Though I'm rather good at PHP, that reminds of C++, I'm a C++ beginner and have never used overloading. Please correct me if you have more experience of C++ than I have and disagree with the piece of advice above.

    • smitha

      Not that am an expert in C++ but overloading is one of the key concepts of C++ through which it implements polymorphism. The advantage is in terms of usability of a function .

      The classic textbook example would be a call a function Area() to find the area of different shapes depending on the number of parameters.
      Overloading would basically be used when you need to do the same thing in different ways. for example finding the area of a rectangle is different from finding the area of a circle.
      Area(int l, int b);
      Area(int r);

      So here the decision as to which function should be executed goes automatically to the compiler and not to the programmer and thereby reducing the number of if-else statements.

    • Vivek

      Overloading is very useful, especially for class constructors.

    • Eiq

      As smitha said, consider several classes that are derived from some base class (triangle, circle and square from object). Now you put thousands of them into vector and want to find their combined area. So you would probably run through some for cycle.
      With overloading you just call area() member function for each one of them. Without overloading you would have to find out what class is the current class and then call appropriate function.

  • smitha

    "If there are multiple arguments, C++ applies the matching rules to each argument in turn. "

    if this is true, then why does the compiler report an ambigous call for the following code:

    #include <iostream.h>
    
    void sum(int, int);
    void sum(double, double);
    int main()
    {
        sum(9.1,8);
        system("pause");
    }
    
    void sum(int x, int y)
    {
         cout<<"dafsdfsad";
         }
         
    void sum(double c, double r)
    {
         cout<<"hhhhh";
    }
  • smitha

    Can functions be overloaded on the basis of one of the arguments being a pointer?
    e.g

    void sum(int);
    void sum(int *);
    

    The compiler doesnt throw an error , so I presume that it is valid, but what I dont understand is that essentially both the arguments are of type int.(even if one contains an address). Kindly explain

  • Gammerz
    void Print(float fValue);
    void Print(struct sValue);
    

    In your above example, I don't understand the syntax of the struct declaration. In section 4.7 (Structs), your function declarations don't contain the keyword "struct", "Employee" is a struct:-

    void PrintInformation(Employee sEmployee)
    {
        using namespace std;
        cout << "ID:   " << sEmployee.nID << endl;
        cout << "Age:  " << sEmployee.nAge << endl;
        cout << "Wage: " << sEmployee.fWage << endl << endl;
    }
    

    Is this a new way of defining a prototype that I don't believe I've come across in your tutorials?

Leave a Reply

You can use these HTML tags

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">