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::vector
container, and<algorithm>
for thestd::for_each
function. - We define a function
print_element
that takes an integer and prints it followed by a space. - We create a vector
numbers
containing the integers 1 through 5. - We use
std::for_each
to applyprint_element
to 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::vector
container, and<algorithm>
for thestd::for_each
function. - We create a vector
numbers
containing the integers 1 through 5. - We use
std::for_each
with 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::vector
container, and<algorithm>
for thestd::for_each
function. - We create a vector
numbers
containing the integers 1 through 5. - We declare an integer variable
sum
and initialize it to 0. This variable will store the sum of all elements in the vector. - We use
std::for_each
with a lambda function that capturessum
by reference ([&sum]
). The lambda function takes each element of the vector as input and adds it tosum
. - After the
std::for_each
call,sum
contains the total sum of all elements in the vector. - We print the value of
sum
to 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_function
that throws astd::runtime_error
if a negative number is encountered. - A vector
numbers
is initialized, including a negative number. - The
std::for_each
function appliesfaulty_function
to 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
FaultyIterator
that throws astd::runtime_error
after iterating over two elements. - An array
arr
is initialized with three elements. - The
std::for_each
function applies theprint_element
function to the elements. The custom iterator throws an exception during iteration. - The exception is caught in the
try-catch
block, and an error message is printed.