Functional Programming in C++: From Lambdas to Algorithms

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Functional Programming in C++: From Lambdas to Composition



Functional programming (FP) is a paradigm where computations are built on the application of pure functions, data immutability, and the absence of side effects. Although C++ was originally a multi-paradigm language, its modern standards (C++11/14/17/20) have introduced powerful tools for FP: lambda expressions, std::function, STL algorithms, coroutines, and even support for monadic patterns. In this article, we'll explore how to write functional code in C++ without losing performance.



1. Fundamentals of Functional Style: Lambdas and std::function



Lambda expressions are the heart of FP in C++. They allow you to create anonymous functions "on the fly," capturing context.



#include <iostream>#include <vector>#include <algorithm>

int main() { std::vector<int> nums = {1, 2, 3, 4, 5}; // Lambda for filtering even numbers auto is_even = [](int x) { return x % 2 == 0; }; // Usage with std::copy_if algorithm std::vector<int> evens; std::copy_if(nums.begin(), nums.end(), std::back_inserter(evens), is_even); for (int n : evens) std::cout << n << " "; // 2 4 return 0;}


Key points about lambdas:

  • Capture — [=] (by value), [&] (by reference), [this] (for class methods).
  • Type — each lambda has a unique type, so std::function or templates are used to pass them to functions.
  • Return value — deduced automatically unless specified otherwise.


std::function — a wrapper for callable objects (functions, lambdas, functors). It's convenient for storage and passing but adds overhead (virtual call).



#include <functional>

void apply_twice(std::function<int(int)> f, int x) { std::cout << f(f(x)) << std::endl; // Composition}

int main() { auto square = [](int x) { return x * x; }; apply_twice(square, 3); // (3^2)^2 = 81 return 0;}


2. STL Algorithms as the Foundation of Functional Chains



STL algorithms (std::transform, std::copy_if, std::accumulate, etc.) fit perfectly into the functional style. They do not modify containers directly but take iterators and return results.



Example: Filtering and transformation (map/filter)



#include <numeric>#include <ranges> // C++20

int main() { std::vector<int> data = {1, 2, 3, 4, 5, 6}; // Classic approach (C++11) std::vector<int> filtered; std::copy_if(data.begin(), data.end(), std::back_inserter(filtered), [](int x) { return x > 3; }); std::vector<int> result; std::transform(filtered.begin(), filtered.end(), std::back_inserter(result), [](int x) { return x * 2; }); // Modern approach with ranges (C++20) auto view = data | std::views::filter([](int x) { return x > 3; }) | std::views::transform([](int x) { return x * 2; }); for (int v : view) std::cout << v << " "; // 8 10 12 return 0;}


Fold with std::accumulate



#include <numeric>

int main() { std::vector<int> nums = {1, 2, 3, 4}; // Sum with initial value 0 int sum = std::accumulate(nums.begin(), nums.end(), 0, [](int a, int b) { return a + b; }); // Product with initial value 1 int prod = std::acc

Blogs

Book Recommendations