Cpp Libs Functional
# C++ Standard Library: ``
The C++ Standard Library `` header provides a robust collection of class templates and function templates. These utilities allow developers to work with **callable objects** (such as standard functions, lambda expressions, member function pointers, and functors) as first-class entities.
By using ``, you can pass behaviors as arguments to algorithms, store them in containers, or return them from other functions, significantly increasing the flexibility and reusability of your code.
---
## Key Concepts
### What is a Function Object (Functor)?
A **function object** (or **functor**) is an instance of a class that overloads the call operator `operator()`. This allows the object to be syntactically invoked just like a standard function call.
```cpp
struct Increment {
int operator()(int x) const { return x + 1; }
};
```
### Callable Objects
In C++, a "callable object" refers to any entity that can be invoked using the `()` operator. This includes:
* Ordinary functions
* Pointers to functions
* Lambda expressions
* Objects of classes that overload `operator()`
* Pointers to member functions
---
## Syntax and Inclusion
To use the utilities provided by the `` header, include it in your source file:
```cpp
#include
```
---
## Core Components
The `` header defines several categories of tools:
### 1. Polymorphic Function Wrappers
* **`std::function`**: A type-safe, polymorphic wrapper that can store, copy, and invoke any callable target with a matching signature.
### 2. Parameter Binding
* **`std::bind`**: Binds arguments to a callable object, creating a new callable object with a modified signature.
* **`std::placeholders`**: Placeholders (`_1`, `_2`, `_3`, etc.) used with `std::bind` to represent unbound arguments.
### 3. Built-in Arithmetic Operations
These classes wrap basic arithmetic operators into reusable function objects:
* `std::plus` (`+`)
* `std::minus` (`-`)
* `std::multiplies` (`*`)
* `std::divides` (`/`)
* `std::modulus` (`%`)
* `std::negate` (unary `-`)
### 4. Built-in Comparison Operations
These classes wrap relational operators, commonly used as comparators in sorting algorithms and associative containers:
* `std::equal_to` (`==`)
* `std::not_equal_to` (`!=`)
* `std::greater` (`>`)
* `std::less` (`<`)
* `std::greater_equal` (`>=`)
* `std::less_equal` (`<=`)
### 5. Logical Operations
* `std::logical_and` (`&&`)
* `std::logical_or` (`||`)
* `std::logical_not` (`!`)
---
## Code Examples
### Example 1: Using `std::function`
`std::function` is highly versatile. It can hold free functions, lambdas, or custom functors.
```cpp
#include
#include
void greet() {
std::cout << "Hello, World!" << std::endl;
}
struct Multiplier {
int factor;
int operator()(int x) const { return x * factor; }
};
int main() {
// 1. Wrapping a standard function
std::function f1 = greet;
f1(); // Output: Hello, World!
// 2. Wrapping a lambda expression
std::function f2 = []() {
std::cout << "Hello, Lambda!" << std::endl;
};
f2(); // Output: Hello, Lambda!
// 3. Wrapping a custom functor (function object)
std::function f3 = Multiplier{3};
std::cout << "Result: " << f3(5) << std::endl; // Output: Result: 15
return 0;
}
```
---
### Example 2: Using `std::bind` and Placeholders
`std::bind` allows you to adapt functions by fixing certain arguments to constant values while leaving others open.
```cpp
#include
#include
int add(int a, int b) {
return a + b;
}
void print_values(int a, int b, int c) {
std::cout << "a: " << a << ", b: " << b << ", c: " << c << std::endl;
}
int main() {
// Bind the first argument of 'add' to 5.
// std::placeholders::_1 represents the first argument passed to bound_add.
auto bound_add = std::bind(add, 5, std::placeholders::_1);
std::cout << "5 + 10 = " << bound_add(10) << std::endl; // Output: 15
// Reordering arguments using placeholders
// Here, the first argument to bound_print goes to 'c', and the second goes to 'a'.
auto bound_print = std::bind(print_values, std::placeholders::_2, 100, std::placeholders::_1);
bound_print(10, 20); // Equivalent to print_values(20, 100, 10)
// Output: a: 20, b: 100, c: 10
return 0;
}
```
---
### Example 3: Using Built-in Comparison Functors
Standard comparison functors are incredibly useful when working with algorithms like `std::sort` or containers like `std::map`.
```cpp
#include
#include
#include
#include
bool custom_compare(int a, int b) {
return a < b;
}
int main() {
std::vector v = {5, 3, 9, 1, 4};
// 1. Sorting using a custom comparison function
std::sort(v.begin(), v.end(), custom_compare);
std::cout << "Sorted with custom function: ";
for (int i : v) {
std::cout << i << " "; // Output: 1 3 4 5 9
}
std::cout << std::endl;
// Reset vector
v = {5, 3, 9, 1, 4};
// 2. Sorting in descending order using std::greater
std::sort(v.begin(), v.end(), std::greater());
std::cout << "Sorted with std::greater: ";
for (int i : v) {
std::cout << i << " "; // Output: 9 5 4 3 1
}
std::cout << std::endl;
return 0;
}
```
---
## Best Practices and Considerations
1. **Prefer Lambdas Over `std::bind`**:
Since C++11, lambda expressions are generally preferred over `std::bind`. Lambdas are easier to read, yield better compiler optimizations, and avoid the complex template syntax associated with `std::bind`.
```cpp
// Using std::bind
auto f_bound = std::bind(add, 5, std::placeholders::_1);
// Using Lambda (Recommended)
auto f_lambda = [](int x) { return add(5, x); };
```
2. **Performance Overhead of `std::function`**:
`std::function` introduces a small runtime overhead due to dynamic memory allocation (type erasure) and virtual-like function calls. If you only need to pass a callable to a template function, prefer using a template parameter instead of wrapping it in `std::function`.
3. **Use `std::ref` and `std::cref` with `std::bind`**:
By default, `std::bind` copies its arguments. If you need to pass an argument by reference, wrap it in `std::ref` or `std::cref` (const reference).
YouTip