Function Overloading
In some languages, like C or Python, a function’s name has to be unique. Suppose you already have a function power that takes a base and an exponent and raises one to the other (like ). Now you need a separate version with integer parameters, but the name power is already taken, so you end up with something like powerInt, two names for the same idea.
C++ drops this restriction. You can give two functions the same name, as long as their parameters are different enough for the compiler to tell them apart. This is called function overloading. It’s useful when the two versions of a function genuinely need different logic, and it lets both versions share one intuitive name.
Overloaded functions: Same name, different jobs
Same name, different logic
You don’t have to write the decimal version of power from scratch. C++ already has a pow function, in the <cmath> header file, that raises a base to an exponent. But pow is built for decimals: it works in floating point and always returns a double, even when you pass in whole numbers. For an integer version, you’d rather work with integers from start to finish.
You can write an integer version of power that uses a plain loop and returns an int, and give it the same name as the decimal version:
Both functions are named power, but their implementations are different:
- The
intversion (lines 4–10) repeatedly multiplies bybase, working entirely with integers, so the result is exact. - The
doubleversion (lines 12–14) leans onstd::pow, which is built to handle fractional exponents (like0.5for a square root).
The two calls to power on lines 16–17 get the right result, regardless of the numeric types you’re working with.
How the compiler picks a version
This happens at compile time, before your program ever runs. When the compiler sees power(2, 10), it checks the argument types against every power function you’ve written, and picks the one whose parameters match best. This is called overload resolution.
Since the compiler knows which power to call at compile time, there’s no additional cost each time the program runs.
What counts as a different overload
The name plus the parameter types (not the return type) make up a function’s signature. Two functions can share a name as long as their signatures differ.
The compiler distinguishes overloads by:
- how many parameters there are
- what types those parameters are
- what order those types appear in
So all three of these can coexist as overloaded functions:
void log(const std::string& message);void log(const std::string& message, int errorCode);void log(int errorCode, const std::string& message);One thing that doesn’t count as a valid overload is a function that differs only in return type. This fails to compile:
int getValue();double getValue(); // error: return type alone isn't enoughTo see why the return type alone isn’t enough, picture calling getValue(); and throwing away the result. There’s no argument to distinguish which getValue you meant, so the compiler has nothing to go on.
Checkpoint
Which pair of function declarations forms a valid overload?
void display(int score);
void display(double score);
vs
int total(int a, int b, int c);
double total(int a, int b, int c);Which of these functions runs against the function call notify(3, "Sam")?
void notify(std::string user, int count);
void notify(int count, std::string user);You’re writing a describe function for a catalog. One version should handle a product’s numeric ID, another should handle its price. Which pair of signatures are valid overloads?