Consider the following function:
1 2 3 4 |
int add(int x, int y) { return x + y; } |
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:
1 2 3 4 5 6 7 8 9 |
int addInteger(int x, int y) { return x + y; } double addDouble(double x, double y) { return x + y; } |
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:
1 2 3 4 |
double add(double x, double y) { return x + y; } |
We now have two versions of add()
in the same scope:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
int add(int x, int y) // integer version { return x + y; } double add(double x, double y) // floating point version { return x + y; } int main() { return 0; } |
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:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
#include <iostream> int add(int x, int y) { return x + y; } double add(double x, double y) { return x + y; } int main() { std::cout << add(1, 2); // calls add(int, int) std::cout << '\n'; std::cout << add(1.2, 3.4); // calls add(double, double) return 0; } |
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:
- Each overloaded function has to be differentiated from the others. We discuss how functions can be differentiated in lesson 8.10 -- Function overload differentiation.
- 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.
![]() |
![]() |
![]() |
what are the rules to be followed in function overloading?
i was expecting name mangling here
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
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.
It's the pointer thing.
Above it says:
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.
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.
Overloading is very useful, especially for class constructors.
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.
"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:
Can functions be overloaded on the basis of one of the arguments being a pointer?
e.g
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
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:-
Is this a new way of defining a prototype that I don't believe I've come across in your tutorials?