Functions: Overloading, Default Args, Inline
ফাংশন — ওভারলোডিং, ডিফল্ট আর্গুমেন্ট
1. Anatomy of a Function
#include <iostream>
// return-type name (parameters)
int add(int a, int b) {
return a + b;
}
int main() {
std::cout << add(3, 4) << "\n";
}
2. Function Overloading
Same name, different parameter types — the compiler picks the right one.
#include <iostream>
#include <string>
int add(int a, int b) { return a + b; }
double add(double a, double b) { return a + b; }
std::string add(std::string a, std::string b) { return a + b; }
int main() {
std::cout << add(2, 3) << "\n";
std::cout << add(2.5, 3.5) << "\n";
std::cout << add(std::string{"hi "}, std::string{"world"}) << "\n";
}
int f(); and double f(); conflict — the call site doesn't say which to pick.
3. Default Arguments
#include <iostream>
int power(int base, int exp = 2) {
int r = 1;
for (int i = 0; i < exp; ++i) r *= base;
return r;
}
int main() {
std::cout << power(5) << "\n"; // 25 (uses default exp=2)
std::cout << power(2, 10) << "\n"; // 1024
}
f(int a, int b = 0) ✓, f(int a = 0, int b) ✗.
4. inline & constexpr Functions
inline hints to the compiler to substitute the function body at the call site (skipping the call overhead).
constexpr functions can be evaluated at compile time:
#include <iostream>
#include <array>
constexpr int factorial(int n) {
return n <= 1 ? 1 : n * factorial(n - 1);
}
int main() {
constexpr int f5 = factorial(5); // computed at compile time
std::array<int, factorial(4)> arr; // size = 24, known at compile time
std::cout << f5 << " " << arr.size() << "\n";
}
5. Trailing Return Type & auto Returns
// Trailing return type (C++11)
auto divide(int a, int b) -> double {
return static_cast<double>(a) / b;
}
// Auto return-type deduction (C++14)
auto multiply(int a, int b) {
return a * b; // deduced to int
}
6. Function Design Rules
- One job: a function should do one thing well.
- Small: if it doesn't fit on a screen, it's probably too big.
- Pure when possible: same input → same output, no side effects.
- Name describes behavior:
computeAverage, notdoStuff. - Fewer parameters: if you have 6+, group them into a struct.
7. Practice Problems
- Write
int max(int a, int b).✨ Show Answer
int max(int a, int b) { return a > b ? a : b; } - Overload
area: one for circle (radius), one for rectangle (w, h).✨ Show Answer
double area(double r) { return 3.14159 * r * r; } double area(double w, double h) { return w * h; } - Why can't you overload by return type only?
✨ Show Answer
Overload resolution uses argument types only. The return type isn't visible at the call site (e.g.
f();alone doesn't say which return type you want). - Write
greet(std::string name = "World").✨ Show Answer
void greet(std::string name = "World") { std::cout << "Hello, " << name << "!\n"; } // greet(); → "Hello, World!" - What does
constexpron a function mean?✨ Show Answer
The function can be evaluated at compile time when called with constant arguments. If called with runtime values, it runs at runtime.
- Write a recursive
constexpr fib(int n).✨ Show Answer
constexpr int fib(int n) { return n < 2 ? n : fib(n-1) + fib(n-2); } - Write a function that returns nothing (void) and prints "Hi".
✨ Show Answer
void sayHi() { std::cout << "Hi\n"; } - Why is
inlinemostly redundant in modern C++?✨ Show Answer
Modern compilers inline aggressively based on profitability —
inlineis just a hint. Its remaining real purpose: allow multiple definitions across translation units (header-defined functions). - Write a function with two default args.
✨ Show Answer
int f(int a, int b = 1, int c = 2) { return a + b + c; } - Write
minoverloaded for int, double, and string.✨ Show Answer
int min(int a, int b) { return a < b ? a : b; } double min(double a, double b) { return a < b ? a : b; } std::string min(std::string a, std::string b) { return a < b ? a : b; }(Better: use a function template — see Module 25.)
- What's a "pure" function?
✨ Show Answer
A function that (1) always returns the same output for the same input and (2) has no side effects (no I/O, no global state mutation). Pure functions are easy to test and reason about.
- Show that
add(2, 2)at compile-time gives 4 with constexpr.✨ Show Answer
constexpr int add(int a, int b) { return a + b; } static_assert(add(2, 2) == 4);static_assertfails to compile if expression isn't true. - Forward declare
fooat top, define at bottom.✨ Show Answer
void foo(); // declaration int main() { foo(); } void foo() { std::cout << "hi\n"; } // definition - Why is C++ pass-by-value (default)?
✨ Show Answer
To prevent surprise mutations from inside the called function. The function gets its own copy. To pass without copying, use
const T&; to allow mutation, useT&.
Summary
Functions are the unit of abstraction. C++ allows overloading by argument types, default arguments (right-to-left), and constexpr functions for compile-time evaluation. Keep functions small, pure when possible, and well-named.