C++ Function Overloading

Multiple functions with the same name

πŸ”„ What is Function Overloading?

Function overloading allows multiple functions with the same name but different parameters. The compiler automatically chooses the correct function based on arguments provided.


// Multiple functions with same name, different parameters
#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) << endl;        // Calls int version
    cout << add(2.5, 3.7) << endl;   // Calls double version
    return 0;
}
                                    

Output:

8
6.2

Ways to Overload Functions

πŸ”’

Different Number

Different number of parameters

void print(int a);
void print(int a, int b);
🏷️

Different Types

Different parameter data types

void print(int a);
void print(double a);
πŸ“‹

Different Order

Different order of parameters

void func(int a, double b);
void func(double a, int b);
⚠️

Not Return Type

Return type alone can't overload

// This won't work!
int func(int a);
double func(int a);

πŸ”Ή Overloading by Number of Parameters

Function overloading by parameter count lets you define multiple versions of a function with different numbers of inputs. For example, a sum() function can handle one, two, or three integers. This provides a clean, intuitive interface where the function adapts based on how many arguments are passed. Overloading by count enhances usability, reduces function name clutter, and is common in utility classes, mathematical libraries, and APIs where operations may scale with input complexity.

#include <iostream>
using namespace std;

// Function with 1 parameter
void display(int a) {
    cout << "Single number: " << a << endl;
}

// Function with 2 parameters
void display(int a, int b) {
    cout << "Two numbers: " << a << " and " << b << endl;
}

// Function with 3 parameters
void display(int a, int b, int c) {
    cout << "Three numbers: " << a << ", " << b << ", " << c << endl;
}

int main() {
    display(10);
    display(20, 30);
    display(40, 50, 60);
    return 0;
}

Output:

Single number: 10
Two numbers: 20 and 30
Three numbers: 40, 50, 60

πŸ”Ή Overloading by Parameter Types

Overloading by parameter type allows functions with the same name to accept different data types. For instance, a multiply() function can work with integers, doubles, or strings, executing type-appropriate logic. This enables polymorphic behavior without inheritance, improves code expressiveness, and supports generic-like functionality in C++. It’s widely used in template helpers, I/O operations, and mathematical libraries to provide consistent interfaces across varied data types while maintaining type safety.

#include <iostream>
using namespace std;

// Function for integers
int multiply(int a, int b) {
    cout << "Multiplying integers: ";
    return a * b;
}

// Function for doubles
double multiply(double a, double b) {
    cout << "Multiplying doubles: ";
    return a * b;
}

// Function for strings (concatenation)
string multiply(string str, int times) {
    cout << "Repeating string: ";
    string result = "";
    for(int i = 0; i < times; i++) {
        result += str;
    }
    return result;
}

int main() {
    cout << multiply(5, 3) << endl;
    cout << multiply(2.5, 4.0) << endl;
    cout << multiply("Hi! ", 3) << endl;
    return 0;
}

Output:

Multiplying integers: 15
Multiplying doubles: 10
Repeating string: Hi! Hi! Hi!

πŸ”Ή Practical Example: Calculator

A calculator implementation demonstrates overloading for operations like addition across different types and arities. Overloaded add() functions can handle integers, doubles, multiple arguments, or even string concatenation. This makes the calculator flexible and user-friendly, mimicking real-world behavior where the same operation applies to diverse inputs. Such practical use of overloading reduces code duplication, improves readability, and showcases how C++ adapts to different contexts efficiently.

#include <iostream>
using namespace std;

// Addition overloads
int calculate(int a, int b) {
    cout << "Adding integers: ";
    return a + b;
}

double calculate(double a, double b) {
    cout << "Adding doubles: ";
    return a + b;
}

// Three parameter addition
int calculate(int a, int b, int c) {
    cout << "Adding three integers: ";
    return a + b + c;
}

// String concatenation
string calculate(string a, string b) {
    cout << "Concatenating strings: ";
    return a + b;
}

int main() {
    cout << calculate(10, 20) << endl;
    cout << calculate(3.14, 2.86) << endl;
    cout << calculate(5, 10, 15) << endl;
    cout << calculate("Hello ", "World!") << endl;
    
    return 0;
}

Output:

Adding integers: 30
Adding doubles: 6
Adding three integers: 30
Concatenating strings: Hello World!

πŸ”Ή Overloading Rules

Important rules to remember when overloading functions:

βœ… Valid Overloading:

  • Different number of parameters: func(int), func(int, int)
  • Different parameter types: func(int), func(double)
  • Different parameter order: func(int, double), func(double, int)

❌ Invalid Overloading:

  • Only return type differs: int func(int), double func(int)
  • Only parameter names differ: func(int a), func(int b)
  • Default parameters causing ambiguity
// Example of ambiguous overloading (DON'T DO THIS)
/*
void print(int a, int b = 10);
void print(int a);
// Calling print(5) would be ambiguous!
*/

// Correct way
void print(int a) {
    cout << "Single parameter: " << a << endl;
}

void print(int a, int b) {
    cout << "Two parameters: " << a << ", " << b << endl;
}

🧠 Test Your Knowledge

Can you overload functions based only on return type?