C++20stladvanced
std::ranges::for_each / for_each_n (C++20 Addition)
C++20 · The Big Four · Compiler flag: -std=c++20
Explanation
Applies a function to each element of a range (or the first N elements). Supports projections, allowing transformation of elements before the function is applied.
Real-World Scenario
Apply a discount to each product's price in an e-commerce catalog.
Quick Snippet
snippet.cpp
#include <ranges>
#include <algorithm>
#include <vector>
struct Product { std::string name; double price; };
std::vector<Product> catalog = {{"Widget", 9.99}, {"Gadget", 19.99}};
std::ranges::for_each(catalog, [](double& p) { p *= 0.9; }, &Product::price);Full Example
ranges_for_each.cpp
// CodeNebula - C++20 Example: ranges::for_each, for_each_n
// Compile: g++ -std=c++20 -Wall -Wextra -o example ranges_for_each.cpp
#include <iostream>
#include <ranges>
#include <vector>
#include <string>
#include <algorithm>
int main() {
std::vector<int> numbers = {1, 2, 3, 4, 5, 6, 7, 8};
// ranges::for_each with a lambda
std::cout << "Doubled: ";
std::ranges::for_each(numbers, [](int n) { std::cout << n * 2 << " "; });
std::cout << "\n";
// for_each with side effects (accumulate a sum)
int sum = 0;
std::ranges::for_each(numbers, [&sum](int n) { sum += n; });
std::cout << "Sum: " << sum << "\n";
// for_each with projection
std::vector<std::string> words = {"hello", "world", "cpp", "twenty"};
std::cout << "\nWord lengths: ";
std::ranges::for_each(words, [](size_t len) { std::cout << len << " "; },
&std::string::size);
std::cout << "\n";
// Modify elements in-place
std::ranges::for_each(numbers, [](int& n) { n *= 10; });
std::cout << "After x10: ";
std::ranges::for_each(numbers, [](int n) { std::cout << n << " "; });
std::cout << "\n";
// for_each on a view (filtered range)
std::vector<int> data = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
std::cout << "\nEven numbers: ";
std::ranges::for_each(data | std::views::filter([](int x) { return x % 2 == 0; }),
[](int n) { std::cout << n << " "; });
std::cout << "\n";
// ranges::for_each_n - apply to first N elements
std::vector<int> vals = {10, 20, 30, 40, 50, 60, 70};
std::cout << "First 4 elements: ";
std::ranges::for_each_n(vals.begin(), 4, [](int n) { std::cout << n << " "; });
std::cout << "\n";
// for_each_n with modification
std::ranges::for_each_n(vals.begin(), 3, [](int& n) { n += 100; });
std::cout << "After adding 100 to first 3: ";
std::ranges::for_each(vals, [](int n) { std::cout << n << " "; });
std::cout << "\n";
// for_each_n with projection
std::cout << "\nFirst 2 word lengths: ";
std::ranges::for_each_n(words.begin(), 2,
[](size_t len) { std::cout << len << " "; },
&std::string::size);
std::cout << "\n";
// Return value of for_each contains the function object
auto result = std::ranges::for_each(data, [count = 0](int) mutable { ++count; });
std::cout << "for_each returned iterator at end: "
<< (result.in == data.end()) << "\n";
return 0;
}
Run command
g++ -std=c++20 -Wall -Wextra -o example ranges_for_each.cpp