C++ Function Overloading

With function overloading, multiple functions can have the same name as long as their parameters are different. This lets you use one clear name for an operation that works on several kinds of data, instead of inventing a new name for each version. The compiler decides which version to call based on the arguments you supply.

One name, several versions

Imagine you want an add function that works for both integers and doubles. Without overloading you might write addInt and addDouble. With overloading you can call both of them add, and C++ picks the correct one by looking at the arguments. Functions that share a name this way are called overloaded functions.

Overloading by parameter type

#include <iostream>
using namespace std;

int add(int a, int b) {
  return a + b;
}

double add(double a, double b) {
  return a + b;
}

int main() {
  cout << add(5, 3) << "\n";      // Calls the int version
  cout << add(4.5, 2.2) << "\n";  // Calls the double version
  return 0;
}

// Outputs:
// 8
// 6.7
Note: The compiler chooses the right overload at compile time by matching the number and types of your arguments to each version's parameters. This is known as overload resolution.

What makes overloads different

Overloaded functions must differ in their parameter list, either in the number of parameters or in their types. The return type alone is not enough to tell two overloads apart, so you cannot have two functions with the same name and same parameters that only differ by return type.

  • Different number of parameters: add(int, int) vs add(int, int, int).
  • Different parameter types: print(int) vs print(string).
  • Return type alone does NOT count: int f(int) and double f(int) is an error.

Overloading by number of parameters

#include <iostream>
using namespace std;

int sum(int a, int b) {
  return a + b;
}

int sum(int a, int b, int c) {
  return a + b + c;
}

int main() {
  cout << sum(2, 3) << "\n";     // 5
  cout << sum(2, 3, 4) << "\n";  // 9
  return 0;
}

// Outputs:
// 5
// 9

Overloading by different types

#include <iostream>
#include <string>
using namespace std;

void describe(int value) {
  cout << "An integer: " << value << "\n";
}

void describe(string value) {
  cout << "A string: " << value << "\n";
}

int main() {
  describe(42);
  describe("hello");
  return 0;
}

// Outputs:
// An integer: 42
// A string: hello
Signature differenceValid overload?Reason
Different parameter typesYesCompiler can tell them apart
Different number of parametersYesCompiler can tell them apart
Only the return type differsNoReturn type is not used for resolution
Only a parameter name differsNoNames don't change the signature
Note: Overloading keeps your code clean, but use it for operations that truly do the same conceptual thing on different data. Giving unrelated actions the same name just because you can will confuse the reader.

Exercise: C++ Function Overloading

In C++, what actually distinguishes two overloaded functions with the same name?