cpp
examples
examples.cpp⚙️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;
}