cpp

examples

examples.cpp⚙️
/**
 * Function Overloading in C++ - Comprehensive Examples
 * 
 * Demonstrates:
 * - Basic function overloading
 * - Overload resolution rules
 * - Type-based overloading
 * - Parameter count overloading
 * - Const overloading
 * - Practical applications
 * 
 * Compile: g++ -std=c++17 -Wall -Wextra examples.cpp -o examples
 * Run: ./examples
 */

#include <iostream>
#include <string>
#include <vector>
#include <cmath>
#include <iomanip>

using namespace std;

// ============================================================
// SECTION 1: BASIC TYPE OVERLOADING
// ============================================================

/**
 * Print functions for different types
 */
void print(int value) {
    cout << "int: " << value << endl;
}

void print(double value) {
    cout << "double: " << fixed << setprecision(2) << value << endl;
}

void print(char value) {
    cout << "char: '" << value << "' (ASCII: " << static_cast<int>(value) << ")" << endl;
}

void print(const string& value) {
    cout << "string: \"" << value << "\"" << endl;
}

void print(bool value) {
    cout << "bool: " << boolalpha << value << endl;
}

// ============================================================
// SECTION 2: PARAMETER COUNT OVERLOADING
// ============================================================

/**
 * Maximum of different numbers of arguments
 */
int maximum(int a, int b) {
    return (a > b) ? a : b;
}

int maximum(int a, int b, int c) {
    return maximum(maximum(a, b), c);
}

int maximum(int a, int b, int c, int d) {
    return maximum(maximum(a, b), maximum(c, d));
}

/**
 * Sum with different counts
 */
int sum(int a, int b) {
    return a + b;
}

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

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

// ============================================================
// SECTION 3: OVERLOADING WITH CONTAINERS
// ============================================================

/**
 * Calculate average for different container types
 */
double average(const vector<int>& nums) {
    if (nums.empty()) return 0.0;
    long long sum = 0;
    for (int n : nums) sum += n;
    return static_cast<double>(sum) / nums.size();
}

double average(const vector<double>& nums) {
    if (nums.empty()) return 0.0;
    double sum = 0.0;
    for (double n : nums) sum += n;
    return sum / nums.size();
}

double average(const int* arr, size_t size) {
    if (size == 0) return 0.0;
    long long sum = 0;
    for (size_t i = 0; i < size; i++) sum += arr[i];
    return static_cast<double>(sum) / size;
}

/**
 * Find element in different containers
 */
int find(const vector<int>& v, int target) {
    for (size_t i = 0; i < v.size(); i++) {
        if (v[i] == target) return static_cast<int>(i);
    }
    return -1;
}

int find(const string& s, char target) {
    for (size_t i = 0; i < s.length(); i++) {
        if (s[i] == target) return static_cast<int>(i);
    }
    return -1;
}

int find(const int* arr, size_t size, int target) {
    for (size_t i = 0; i < size; i++) {
        if (arr[i] == target) return static_cast<int>(i);
    }
    return -1;
}

// ============================================================
// SECTION 4: CONSTRUCTOR-LIKE FACTORY OVERLOADING
// ============================================================

struct Point {
    double x, y;
    
    string toString() const {
        return "(" + to_string(x) + ", " + to_string(y) + ")";
    }
};

// Factory functions with overloading
Point makePoint() {
    return {0.0, 0.0};  // Origin
}

Point makePoint(double value) {
    return {value, value};  // Same x and y
}

Point makePoint(double x, double y) {
    return {x, y};  // Explicit coordinates
}

Point makePoint(const Point& other) {
    return {other.x, other.y};  // Copy
}

// ============================================================
// SECTION 5: STRING CONVERSION OVERLOADING
// ============================================================

string toString(int value) {
    return to_string(value);
}

string toString(double value, int precision = 2) {
    ostringstream oss;
    oss << fixed << setprecision(precision) << value;
    return oss.str();
}

string toString(bool value) {
    return value ? "true" : "false";
}

string toString(const vector<int>& v) {
    string result = "[";
    for (size_t i = 0; i < v.size(); i++) {
        result += to_string(v[i]);
        if (i < v.size() - 1) result += ", ";
    }
    return result + "]";
}

string toString(const Point& p) {
    return "Point" + p.toString();
}

// ============================================================
// SECTION 6: MATHEMATICAL OPERATIONS
// ============================================================

/**
 * Power function with integer and double versions
 */
int power(int base, int exp) {
    int result = 1;
    for (int i = 0; i < exp; i++) {
        result *= base;
    }
    return result;
}

double power(double base, int exp) {
    return pow(base, exp);
}

double power(double base, double exp) {
    return pow(base, exp);
}

/**
 * Absolute value
 */
int absolute(int x) {
    return (x < 0) ? -x : x;
}

double absolute(double x) {
    return (x < 0) ? -x : x;
}

long long absolute(long long x) {
    return (x < 0) ? -x : x;
}

// ============================================================
// SECTION 7: CONST OVERLOADING IN CLASS
// ============================================================

class NumberArray {
private:
    vector<int> data;
    
public:
    NumberArray(initializer_list<int> init) : data(init) {}
    
    // Non-const version - allows modification
    int& at(size_t index) {
        cout << "  [non-const at() called]" << endl;
        return data.at(index);
    }
    
    // Const version - read-only access
    const int& at(size_t index) const {
        cout << "  [const at() called]" << endl;
        return data.at(index);
    }
    
    // Non-const - returns modifiable reference
    int& front() { return data.front(); }
    
    // Const - returns const reference
    const int& front() const { return data.front(); }
    
    size_t size() const { return data.size(); }
    
    void print() const {
        cout << "  [";
        for (size_t i = 0; i < data.size(); i++) {
            cout << data[i];
            if (i < data.size() - 1) cout << ", ";
        }
        cout << "]" << endl;
    }
};

// ============================================================
// SECTION 8: RECURSIVE OVERLOADING
// ============================================================

// Base case: no arguments
int countArgs() {
    return 0;
}

// One argument
template<typename T>
int countArgs(T first) {
    (void)first;  // Unused
    return 1;
}

// Multiple arguments - recursive
template<typename T, typename... Args>
int countArgs(T first, Args... rest) {
    (void)first;
    return 1 + countArgs(rest...);
}

// ============================================================
// SECTION 9: PRACTICAL EXAMPLES
// ============================================================

/**
 * Format currency
 */
string formatMoney(int cents) {
    int dollars = cents / 100;
    int remainder = cents % 100;
    return "$" + to_string(dollars) + "." + 
           (remainder < 10 ? "0" : "") + to_string(remainder);
}

string formatMoney(double amount) {
    int cents = static_cast<int>(amount * 100 + 0.5);
    return formatMoney(cents);
}

string formatMoney(double amount, const string& currency) {
    ostringstream oss;
    oss << currency << fixed << setprecision(2) << amount;
    return oss.str();
}

/**
 * Distance calculations
 */
double distance(double x1, double y1, double x2, double y2) {
    return sqrt(pow(x2 - x1, 2) + pow(y2 - y1, 2));
}

double distance(const Point& p1, const Point& p2) {
    return distance(p1.x, p1.y, p2.x, p2.y);
}

double distance(const Point& p) {
    return distance(0, 0, p.x, p.y);  // Distance from origin
}

// ============================================================
// DEMONSTRATION FUNCTIONS
// ============================================================

void demonstrateTypeOverloading() {
    cout << "\n╔══════════════════════════════════════════════════════════════╗" << endl;
    cout << "║              SECTION 1: Type Overloading                     ║" << endl;
    cout << "╚══════════════════════════════════════════════════════════════╝" << endl;
    
    cout << "Calling print() with different types:" << endl;
    print(42);
    print(3.14159);
    print('A');
    print("Hello, World!");
    print(true);
}

void demonstrateParameterCountOverloading() {
    cout << "\n╔══════════════════════════════════════════════════════════════╗" << endl;
    cout << "║           SECTION 2: Parameter Count Overloading             ║" << endl;
    cout << "╚══════════════════════════════════════════════════════════════╝" << endl;
    
    cout << "maximum(3, 7) = " << maximum(3, 7) << endl;
    cout << "maximum(3, 7, 5) = " << maximum(3, 7, 5) << endl;
    cout << "maximum(3, 7, 5, 9) = " << maximum(3, 7, 5, 9) << endl;
    
    cout << "\nsum(1, 2) = " << sum(1, 2) << endl;
    cout << "sum(1, 2, 3) = " << sum(1, 2, 3) << endl;
    cout << "sum(1, 2, 3, 4) = " << sum(1, 2, 3, 4) << endl;
}

void demonstrateContainerOverloading() {
    cout << "\n╔══════════════════════════════════════════════════════════════╗" << endl;
    cout << "║           SECTION 3: Container Overloading                   ║" << endl;
    cout << "╚══════════════════════════════════════════════════════════════╝" << endl;
    
    vector<int> intVec = {1, 2, 3, 4, 5};
    vector<double> doubleVec = {1.5, 2.5, 3.5};
    int arr[] = {10, 20, 30, 40};
    
    cout << "average(vector<int>) = " << average(intVec) << endl;
    cout << "average(vector<double>) = " << average(doubleVec) << endl;
    cout << "average(int[]) = " << average(arr, 4) << endl;
    
    cout << "\nfind(vector, 3) = " << find(intVec, 3) << endl;
    cout << "find(\"hello\", 'l') = " << find("hello", 'l') << endl;
    cout << "find(arr, 4, 30) = " << find(arr, 4, 30) << endl;
}

void demonstrateFactoryOverloading() {
    cout << "\n╔══════════════════════════════════════════════════════════════╗" << endl;
    cout << "║           SECTION 4: Factory Function Overloading            ║" << endl;
    cout << "╚══════════════════════════════════════════════════════════════╝" << endl;
    
    Point p1 = makePoint();
    Point p2 = makePoint(5.0);
    Point p3 = makePoint(3.0, 4.0);
    Point p4 = makePoint(p3);
    
    cout << "makePoint() = " << p1.toString() << endl;
    cout << "makePoint(5.0) = " << p2.toString() << endl;
    cout << "makePoint(3.0, 4.0) = " << p3.toString() << endl;
    cout << "makePoint(p3) = " << p4.toString() << endl;
}

void demonstrateToStringOverloading() {
    cout << "\n╔══════════════════════════════════════════════════════════════╗" << endl;
    cout << "║           SECTION 5: toString Overloading                    ║" << endl;
    cout << "╚══════════════════════════════════════════════════════════════╝" << endl;
    
    cout << "toString(42) = \"" << toString(42) << "\"" << endl;
    cout << "toString(3.14159) = \"" << toString(3.14159) << "\"" << endl;
    cout << "toString(3.14159, 4) = \"" << toString(3.14159, 4) << "\"" << endl;
    cout << "toString(true) = \"" << toString(true) << "\"" << endl;
    cout << "toString(vector) = \"" << toString(vector<int>{1, 2, 3}) << "\"" << endl;
    cout << "toString(Point) = \"" << toString(makePoint(5, 10)) << "\"" << endl;
}

void demonstrateMathOverloading() {
    cout << "\n╔══════════════════════════════════════════════════════════════╗" << endl;
    cout << "║           SECTION 6: Math Function Overloading               ║" << endl;
    cout << "╚══════════════════════════════════════════════════════════════╝" << endl;
    
    cout << "power(2, 10) [int] = " << power(2, 10) << endl;
    cout << "power(2.5, 3) [double,int] = " << power(2.5, 3) << endl;
    cout << "power(2.0, 0.5) [double,double] = " << power(2.0, 0.5) << endl;
    
    cout << "\nabsolute(-42) = " << absolute(-42) << endl;
    cout << "absolute(-3.14) = " << absolute(-3.14) << endl;
    cout << "absolute(-1000000000LL) = " << absolute(-1000000000LL) << endl;
}

void demonstrateConstOverloading() {
    cout << "\n╔══════════════════════════════════════════════════════════════╗" << endl;
    cout << "║           SECTION 7: Const Overloading                       ║" << endl;
    cout << "╚══════════════════════════════════════════════════════════════╝" << endl;
    
    NumberArray arr = {1, 2, 3, 4, 5};
    const NumberArray constArr = {10, 20, 30};
    
    cout << "Non-const object - arr.at(0):" << endl;
    arr.at(0) = 100;  // Calls non-const version, can modify
    arr.print();
    
    cout << "\nConst object - constArr.at(0):" << endl;
    int val = constArr.at(0);  // Calls const version
    cout << "  Value: " << val << endl;
}

void demonstratePracticalExamples() {
    cout << "\n╔══════════════════════════════════════════════════════════════╗" << endl;
    cout << "║           SECTION 8: Practical Examples                      ║" << endl;
    cout << "╚══════════════════════════════════════════════════════════════╝" << endl;
    
    cout << "Money formatting:" << endl;
    cout << "  formatMoney(1234) = " << formatMoney(1234) << endl;
    cout << "  formatMoney(19.99) = " << formatMoney(19.99) << endl;
    cout << "  formatMoney(99.99, \"€\") = " << formatMoney(99.99, "€") << endl;
    
    cout << "\nDistance calculations:" << endl;
    Point origin = makePoint();
    Point p1 = makePoint(3, 4);
    Point p2 = makePoint(6, 8);
    
    cout << "  distance(0,0 to 3,4) = " << distance(0, 0, 3, 4) << endl;
    cout << "  distance(p1, p2) = " << distance(p1, p2) << endl;
    cout << "  distance(p1) [from origin] = " << distance(p1) << endl;
    
    cout << "\nArgument counting (variadic):" << endl;
    cout << "  countArgs() = " << countArgs() << endl;
    cout << "  countArgs(1) = " << countArgs(1) << endl;
    cout << "  countArgs(1, 2, 3) = " << countArgs(1, 2, 3) << endl;
    cout << "  countArgs(1, \"hello\", 3.14, 'x') = " 
         << countArgs(1, "hello", 3.14, 'x') << endl;
}

// ============================================================
// MAIN FUNCTION
// ============================================================

int main() {
    cout << "╔════════════════════════════════════════════════════════════════════╗" << endl;
    cout << "║              C++ FUNCTION OVERLOADING EXAMPLES                     ║" << endl;
    cout << "║           Multiple Functions with the Same Name                    ║" << endl;
    cout << "╚════════════════════════════════════════════════════════════════════╝" << endl;
    
    demonstrateTypeOverloading();
    demonstrateParameterCountOverloading();
    demonstrateContainerOverloading();
    demonstrateFactoryOverloading();
    demonstrateToStringOverloading();
    demonstrateMathOverloading();
    demonstrateConstOverloading();
    demonstratePracticalExamples();
    
    cout << "\n╔════════════════════════════════════════════════════════════════════╗" << endl;
    cout << "║                       Examples Complete!                           ║" << endl;
    cout << "╚════════════════════════════════════════════════════════════════════╝" << endl;
    
    return 0;
}
Examples - C++ Tutorial | DeepML