Functions¶
Functions are the building blocks of C++ codebases. They encapsulate logic, promote code reuse, and control execution paths. Modern C++ provides highly optimized ways to declare, parameterize, and execute functional logic, including inline execution and lambdas.
1. Declarations vs. Definitions¶
To keep source code organized, C++ splits code components into:
- Declaration (Prototype): Specifies the function's interface (name, parameters, and return type). It does not contain code. Typically put in header files (.hpp or .h).
- Definition: The actual implementation containing the logic. Typically written in source files (.cpp).
2. Parameter Passing Semantics¶
In C++, how you pass arguments to a function has massive implications for performance and safety.
1. Pass by Value¶
The compiler creates a copy of the argument. Modifications inside the function do not affect the original variable.
int, double, bool, char.
2. Pass by Reference (&)¶
The function parameter becomes an alias for the original argument. Modifications directly affect the caller's variable.
Best for: output parameters or modifiable states.3. Pass by Const Reference (const &)¶
Passes a reference to avoid copying, but the compiler prevents any modification of the parameter.
std::string, std::vector, and custom classes/structs.
3. Function Overloading & Name Mangling¶
You can define multiple functions with the same name, as long as their parameter types or quantities differ. This is called Function Overloading.
How Name Mangling Works¶
Behind the scenes, the C++ compiler distinguishes overloaded functions by generating unique names for the linker. This is called Name Mangling. For example, the function void print(int) might compile to a linker symbol like _Z5printi, while void print(double) becomes _Z5printd.
4. Lambda Expressions¶
Lambdas are anonymous, in-line functions. They are extremely powerful for temporary operations (e.g., passing predicates to STL algorithms).
Lambda Syntax Anatomy¶
[capture_list]: Defines what variables from the surrounding scope are accessible inside the lambda.[]: Empty capture. No outside variables are accessible.[=]: Capture all variables in the surrounding scope by value (read-only copy).[&]: Capture all variables in the surrounding scope by reference (modifiable).[x, &y]: Capturexby value andyby reference.
mutable: By default, lambdas capturing by value are read-only. Addingmutableallows you to modify variables captured by value inside the lambda body (though it won't affect the external variable).
5. Compile-Time Functions: constexpr and consteval¶
constexpr Functions¶
A constexpr function can be evaluated at compile time if the inputs are known at compile time. If the inputs are only known at runtime, it runs as a standard runtime function.
consteval Functions (C++20)¶
Introduced in C++20, consteval functions (also known as immediate functions) must be evaluated at compile time. Running them with runtime parameters generates a compiler error.
6. Trailing Return Types¶
Modern C++ provides two ways to specify return types: 1. Auto Deduction (C++14): The compiler deduces the return type automatically from the return statement. 2. Trailing Return Type: Useful when the return type depends on the parameters or when writing complex template functions.
Related Guides¶
- Basic Syntax — Variable types and initialization.
- Templates — Generic template functions.