C++ <algorithm> std::for_each
The std::for_each function template in C++ applies a specified function to each element in a given range. It is part of the C++ Standard Library’s <algorithm> header and is useful for performing operations on each element of a container without explicitly writing a loop.
Syntax of std::for_each
template <class InputIterator, class Function>
Function for_each(InputIterator first, InputIterator last, Function fn);
Parameters of std::for_each
| Parameter | Description |
|---|---|
first | An input iterator to the initial position in a sequence. |
last | An input iterator to the final position in a sequence (one past the last element). |
fn | A unary function that accepts an element in the range as an argument. The function can modify the elements if the input iterator points to a modifiable sequence. |
Return Value of std::for_each
Returns the function object fn after it has been applied to each element in the range [first, last). This allows fn to maintain state that can be examined after the algorithm completes.
Exceptions for std::for_each
Throws if the application of fn to an element throws an exception, or if any operation on the iterators throws. Note that invalid arguments cause undefined behavior.
Examples for for_each Function
Example 1: Using std::for_each to Print Elements
In this example, we use std::for_each to print each element of a vector.
Program
#include <iostream>
#include <vector>
#include <algorithm> // For std::for_each
void print_element(int n) {
std::cout << n << " ";
}
int main() {
std::vector<int> numbers = {1, 2, 3, 4, 5};
std::for_each(numbers.begin(), numbers.end(), print_element);
std::cout << std::endl;
return 0;
}
Output
1 2 3 4 5
Explanation
- We include the necessary headers:
<iostream>for input/output operations,<vector>for thestd::vectorcontainer, and<algorithm>for thestd::for_eachfunction. - We define a function
print_elementthat takes an integer and prints it followed by a space. - We create a vector
numberscontaining the integers 1 through 5. - We use
std::for_eachto applyprint_elementto each element in the vector. - After the loop, we print a newline character to ensure the output is properly formatted.
Example 2: Using std::for_each with a Lambda Function
This example demonstrates how to use std::for_each with a lambda function to increment each element in a vector.
Program
#include <iostream>
#include <vector>
#include <algorithm> // For std::for_each
int main() {
std::vector<int> numbers = {1, 2, 3, 4, 5};
std::for_each(numbers.begin(), numbers.end(), [](int &n) {
n += 1;
});
for (int n : numbers) {
std::cout << n << " ";
}
std::cout << std::endl;
return 0;
}
Output
2 3 4 5 6
Explanation
- We include the necessary headers:
<iostream>for input/output operations,<vector>for thestd::vectorcontainer, and<algorithm>for thestd::for_eachfunction. - We create a vector
numberscontaining the integers 1 through 5. - We use
std::for_eachwith a lambda function that takes an integer reference and increments it by 1. - We then use a range-based for loop to print each element in the modified vector.
- After the loop, we print a newline character to ensure the output is properly formatted.
Example 3: Using std::for_each to Accumulate a Sum
In this example, we use std::for_each to calculate the sum of elements in a vector by capturing a local variable in a lambda function.
Program
#include <iostream>
#include <vector>
#include <algorithm> // For std::for_each
int main() {
std::vector<int> numbers = {1, 2, 3, 4, 5};
int sum = 0;
std::for_each(numbers.begin(), numbers.end(), [&sum](int n) {
sum += n;
});
std::cout << "Sum: " << sum << std::endl;
return 0;
}
Output
Sum: 15
Explanation
- We include the necessary headers:
<iostream>for input/output operations,<vector>for thestd::vectorcontainer, and<algorithm>for thestd::for_eachfunction. - We create a vector
numberscontaining the integers 1 through 5. - We declare an integer variable
sumand initialize it to 0. This variable will store the sum of all elements in the vector. - We use
std::for_eachwith a lambda function that capturessumby reference ([&sum]). The lambda function takes each element of the vector as input and adds it tosum. - After the
std::for_eachcall,sumcontains the total sum of all elements in the vector. - We print the value of
sumto the console usingstd::cout.
Examples for Exception Handling in std::for_each
The std::for_each function can throw exceptions if the provided function object (fn) or any operation on the iterators throws an exception. Here are examples demonstrating these scenarios:
Example 1: Function Object Throws an Exception
This example demonstrates a case where the function object passed to std::for_each throws an exception during execution.
Program
#include <iostream>
#include <vector>
#include <algorithm>
#include <stdexcept>
void faulty_function(int n) {
if (n < 0) {
throw std::runtime_error("Negative number encountered.");
}
std::cout << n << " ";
}
int main() {
std::vector numbers = {1, 2, -3, 4, 5};
try {
std::for_each(numbers.begin(), numbers.end(), faulty_function);
} catch (const std::runtime_error& e) {
std::cout << "\nException caught: " << e.what() << std::endl;
}
return 0;
}
Output
1 2
Exception caught: Negative number encountered.
Explanation
- The program defines a function
faulty_functionthat throws astd::runtime_errorif a negative number is encountered. - A vector
numbersis initialized, including a negative number. - The
std::for_eachfunction appliesfaulty_functionto each element in the vector. When it encounters the negative number, the function throws an exception. - The exception is caught in the try-catch block, and an error message is printed.
Example 2: Iterator Throws an Exception
This example demonstrates a case where a custom iterator throws an exception during iteration.
Program
#include <iostream>
#include <vector>
#include <algorithm>
#include <stdexcept>
class FaultyIterator {
public:
using iterator_category = std::input_iterator_tag;
using value_type = int;
using difference_type = std::ptrdiff_t;
using pointer = const int*;
using reference = const int&;
FaultyIterator(const int* ptr, bool fail_after = false)
: ptr(ptr), fail_after(fail_after), count(0) {}
reference operator*() const {
if (fail_after && count >= 2) {
throw std::runtime_error("Iterator error.");
}
return *ptr;
}
FaultyIterator& operator++() {
++ptr;
++count;
return *this;
}
bool operator!=(const FaultyIterator& other) const {
return ptr != other.ptr;
}
bool operator==(const FaultyIterator& other) const {
return ptr == other.ptr;
}
private:
const int* ptr;
bool fail_after;
int count;
};
void print_element(int n) {
std::cout << n << " ";
}
int main() {
int arr[] = {1, 2, 3};
try {
std::for_each(
FaultyIterator(arr, true),
FaultyIterator(arr + 3),
print_element
);
} catch (const std::runtime_error& e) {
std::cout << "\nException caught: " << e.what() << std::endl;
}
return 0;
}
Output
1 2
Exception caught: Iterator error.
Explanation
- The program defines a custom iterator
FaultyIteratorthat throws astd::runtime_errorafter iterating over two elements. - An array
arris initialized with three elements. - The
std::for_eachfunction applies theprint_elementfunction to the elements. The custom iterator throws an exception during iteration. - The exception is caught in the
try-catchblock, and an error message is printed.
