Functions
2 min read
Functions
A function is a named block of code that takes inputs (parameters) and produces an output (return value). Functions let you name and reuse logic.
Basic function
#include <iostream>
int add(int a, int b) {
return a + b;
}
int main() {
std::cout << add(3, 4) << "\n"; // 7
}
The signature int add(int a, int b) declares: return type int, name add, parameters a and b of type int.
Forward declarations
A function must be declared before its call site. A forward declaration separates the declaration from the definition:
int add(int a, int b); // declaration
int main() {
std::cout << add(3, 4) << "\n";
}
int add(int a, int b) { // definition
return a + b;
}
void functions
A function that performs an action without returning a value uses void:
#include <iostream>
#include <string>
void greet(const std::string& name) {
std::cout << "Hello, " << name << "!\n";
}
Pass by value vs. pass by reference
By default, arguments are copied into the function (pass by value). For large objects, use a reference to avoid the copy:
#include <vector>
#include <numeric>
// Pass by const reference: no copy, no modification
double average(const std::vector<int>& v) {
if (v.empty()) return 0.0;
return static_cast<double>(std::accumulate(v.begin(), v.end(), 0)) / v.size();
}
// Pass by reference: modifies the caller's vector
void double_values(std::vector<int>& v) {
for (int& x : v) x *= 2;
}
As a rule of thumb: pass primitives (int, double, etc.) by value; pass larger objects by const T& for read access and T& for modification.
Multiple return values
C++ functions return one value. For multiple values, return a struct or use out-parameters:
#include <utility>
std::pair<int, int> divide_with_remainder(int a, int b) {
return {a / b, a % b};
}
int main() {
auto [quotient, remainder] = divide_with_remainder(17, 5);
// quotient == 3, remainder == 2
}
Structured bindings (auto [a, b] = ...) unpack pairs and tuples cleanly.
Inline functions
The inline keyword suggests that the compiler substitute the function body at the call site instead of generating a function call. Modern compilers inline small functions automatically regardless of the keyword. It is most useful in headers to allow multiple translation units to include the definition:
inline int square(int x) { return x * x; }
[[nodiscard]]
Marking a function [[nodiscard]] makes the compiler warn if the return value is ignored — useful for error codes:
[[nodiscard]] bool save_file(const std::string& path);
// save_file("data.txt"); // warning: ignoring return value
Learn modern C++ through working code. Each chapter introduces one concept — variables, functions, classes, templates, smart pointers, concurrency — with a clear example, a line-by-line explanation, and notes on how it applies in real programs.
View book →