from/prod
← All companies

THE COMPANY INDEX TRACKED BLOG

Bartlomiej Filipek

Ideas, decisions, and lessons from the team.

bfilipek.com (opens on the source site)
27Posts tracked
2 weeks agoLatest publication
0.8Posts / month over the last 12 months

Latest writing

20 of 27 posts

Using C++17 std::optional (opens on the source site)

Let’s take a pair of two types - what can you do with such composition? In this article, I’ll describe std::optional - a helper “vocabulary” type added in C++17. It’s a wrapper that either contains a value of your type or is empty. Let’s see where it can be useful and how you can use it. Updated in September 2026 with C++20, C++23, and C++26 changes. Intro By adding the boolean flag to other types, you can achieve a thing called “nullable types”. As mentioned, the flag is used to indicate whether the value is available or not. Such wrapper represents an object that might be empty in an…

Read at the source

C++26: Standard Library Hardening Experiments (opens on the source site)

“Hardening” seems to be a very popular term in the C++ World in 2026. In this article we’ll explore what this word means and see some core examples. Can a hardened library make C++ fully safe? Let’s find out. The Core Idea When you learned about std::vector you may remember that you can access an element at the i-th position using at least two expressions: std::vectorint> v { 1, 2, 3, 4 }; v[i] = 10; // for some i v.at(j) = 11; // for some j The main difference between those two is that [] is unchecked (and can generate undefined behaviour if you try to access an element which is not there),…

Read at the source

Understanding std::counting_semaphore and std::binary_semaphore from C++20 (opens on the source site)

This article explains the two semaphore types introduced in C++20: std::counting_semaphore and std::binary_semaphore. We’ll first use a counting semaphore to limit how many threads can operate at the same time. Then we’ll use a binary semaphore to send a signal between threads. We’ll also look at timed waiting, a small RAII helper, and a few more details. Note: The synchronization features discussed here are available in C++20. The examples use C++23 std::println for cleaner output. Let’s go. Basics A mutex works well when only one thread should enter a protected section at a time. But…

Read at the source

How to join or concat ranges, C++26 (opens on the source site)

Modern C++ continuously improves its range library to provide more expressive, flexible, and efficient ways to manipulate collections. Usually, when you wanted to concatenate or flatten ranges, you’d use raw loops or custom algorithms. With C++’s range adaptors, we now have an elegant and efficient way to process collections lazily without unnecessary allocations. In this post, we will explore three powerful range adaptors introduced in different C++ standards: std::ranges::concat_view (C++26) std::ranges::join_view (C++20) std::ranges::join_with_view (C++23) Let’s break down their…

Read at the source

15 Different Ways to Filter Containers in Modern C++ (opens on the source site)

Do you know how many ways we can implement a filter function in C++? While the problem is relatively easy to understand - take a container, copy elements that match a predicate, and return a new container - it’s good to exercise with the C++ Standard Library and check a few ideas. We can also apply some Modern C++ techniques, including C++23. Let’s start! The article was written in 2021 and recently updated in late 2025 to include additional techniques from C++23. Additionally, the text is also republished on the ACCU website: ACCU Overload, 33: 15 Different Ways to Filter Containers in…

Read at the source

Understanding std::shared_mutex from C++17 (opens on the source site)

In this article, we’ll start with a basic example using std::mutex, look at its limitations, and then introduce std::shared_mutex, a reader-writer mutex added in C++17. Even in 2026, with many new concurrency features available, std::shared_mutex is still a valuable and practical tool. Let’s jump in. A Simple Thread-Safe Counter with std::mutex We’ll begin with a small example (a standard “hello world” for this type of mutexes): a counter object that multiple threads can access: #include class Counter { public: int get() const { std::lock_guardstd::mutex> lock(mutex_); return value_; } void…

Read at the source

IIFE for Complex Initialization (opens on the source site)

What do you do when the code for a variable initialization is complicated? Do you move it to another method or write inside the current scope? In this blog post, I’d like to present a trick that allows computing a value for a variable, even a const variable, with a compact notation. Updated in Jan 2026: improved code, added C++26 section, added [&] section, updated code samples and added links to Compiler Explorer. Intro I hope you’re initializing most variables as const (so that the code is more explicit, and also compiler can reason better about the code and optimize). For example, it’s…

Read at the source

7 Practical std::chrono Calendar Examples (C++20) (opens on the source site)

This article collects small, self-contained, and practical examples for working with std::chrono calendar types. The previous blog post - see Exploring C++20 std::chrono - Calendar Types - C++ Stories - focused on the building blocks: calendar types, operators, and arithmetic rules. In this post, we’ll focus on practical examples like: What’s the last business day of the month? When is the third Friday in June? How many days since the start of the year? What happens when I add a month to January 31? And a few more Let’s start. 1. Which day of the year is that? Let’s begin with a simple…

Read at the source

Exploring C++20 std::chrono - Calendar Types (opens on the source site)

Before C++20, gave us a solid foundation for working with clocks, durations, and time points - but it didn’t really know anything about the civil calendar. If you needed to represent “March 15”, check whether a date is valid, compute “the third Monday of November”, or add a few months to a date, you had to rely on custom utilities, std::tm, or external libraries like Howard Hinnant’s excellent date. C++20 finally fills this gap by standardising a complete set of calendar types: year, month, day, weekday, year_month_day, month_day_last, and many more. These types let you express dates in a…

Read at the source

C++ Templates: How to Iterate through std::tuple: C++26 Packs and Expansion Statements (opens on the source site)

In part 1 of this mini-series, we looked at the basics of iterating over a std::tuple using index_sequence and fold expressions. In part 2, we simplified things with std::apply and even created helpers like for_each_tuple and transform_tuple. So far, we used C++ features up to C++20/23… but now, in C++26, we finally get language-level tools that make tuple iteration straightforward and expressive. In this article, we’ll explore two new techniques: Structured bindings can introduce a pack - P1061 - turn a tuple into a pack of variables. Expansion statements P1306 - the ultimate “compile-time…

Read at the source

C++ Templates: How to Iterate through std::tuple: std::apply and More (opens on the source site)

In the previous article on the tuple iteration, we covered the basics. As a result, we implemented a function template that took a tuple and could nicely print it to the output. There was also a version with operator . Today we can go further and see some other techniques. The first one is with std::apply from C++17, a helper function for tuples. Today’s article will also cover some strategies to make the iteration more generic and handle custom callable objects, not just printing. This is the second part of the small series. See the first article here where we discuss the basics. And see the…

Read at the source

Structured bindings in C++17, 8 years later (opens on the source site)

Structured binding is a C++17 feature that allows you to bind multiple variables to the elements of a structured object, such as a tuple or struct. This can make your code more concise and easier to read, especially when working with complex data structures. On this blog, we already covered this functionality, but we’ll talk about some good C++26 additions and real code use cases. Iterating through maps An excellent demonstration of structured bindings is an iteration through a map object. If you have a std::map of elements, you might know that internally, they are stored as pairs of . Now,…

Read at the source

How to Avoid Thread-Safety Cost for Functions' static Variables (opens on the source site)

In this blog post, we’ll look at static variables defined in a function scope. We’ll see how they are implemented and how to use them. What’s more, we’ll discuss several cases where we can avoid extra thread-safety cost. Let’s start. Introduction As you may know, C++ offers a way to define static variables in a function/block scope: void foo() { static int counter = 0; ++counter; } Above, the counter variable will be initialized and created when foo() is invoked for the first time. In other words, a static local variable is initialized lazily. The counter is kept “outside” the function’s…

Read at the source

How to Split Ranges in C++23 (opens on the source site)

In this blog post, we’ll continue looking at ranges and this time explore ways to split them into sub-ranges. So we’ll take a look at views::split, views::chunk, and views::chunk_by. We’ll walk through two examples for each adaptor: one simple and one slightly more advanced, to highlight their practical uses. Let’s go. Splitting Ranges with views::split, C++20 If you want to split a range using some “delimeter,” then views::split (or ranges::split_view) will do the job. template ranges::forward_range V, ranges::forward_range Pattern > // .. requires... class split_vie : public…

Read at the source

Views as Data Members for Custom Iterators (opens on the source site)

In this blog post, we’ll write an iterator that works with a vector of vectors. We’ll explore a “manual” version as well as leverage C++20 ranges/views to do the hard work. The problem statement What’s the use case? See this popular interview question (found in DailyCodingProblem: https://www.dailycodingproblem.com/) Implement a 2D iterator class. It will be initialized with an array of arrays and should implement the following methods: next() : returns the next element in the array of arrays. If there are no more elements, raise an exception. has_next() : returns whether or not the iterator…

Read at the source

Details of std::mdspan from C++23 (opens on the source site)

In this article, we’ll see details of std::mdspan, a new view type tailored to multidimensional data. We’ll go through type declaration, creation techniques, and options to customize the internal functionality. Type declaration The type is declared in the following way: template class T, class Extents, class LayoutPolicy = std::layout_right, class AccessorPolicy = std::default_accessorT> > class mdspan; And it has its own header . The main proposal for this feature can be found at https://wg21.link/P0009 Following the pattern from std::span, we have a few options to create mdspan: with…

Read at the source

Adjacency Matrix and std::mdspan, C++23 (opens on the source site)

In graph theory, an adjacency matrix is a square matrix used to represent a finite (and usually dense) graph. The elements of the matrix indicate whether pairs of vertices are adjacent or not, and in weighted graphs, they store the edge weights. In many beginner-level tutorials, adjacency matrices are implemented using vector of vectors (nested dynamic arrays), but this approach has inefficiencies due to multiple memory allocations. C++23 introduces std::mdspan, which provides a more efficient way to handle multidimensional data structures without the overhead of nested containers. In this…

Read at the source

How to use std::span from C++20 (opens on the source site)

In this article, we’ll look at std::span, which has been available since C++20. This “view” type is more generic than string_view and can help work with arbitrary contiguous collections. Updated in Feb 2025: added section about returning spans and C++26 improvements (.at() and creatoion from initializer list). A Motivating Example Here’s an example that illustrates the primary use case for std::span: In traditional C (or low-level C++), you’d pass an array to a function using a pointer and a size like this: void process_array(int* arr, std::size_t size) { for(std::size_t i = 0; i size; ++i) {…

Read at the source

Improving Code Safety in C++26: Managers and Dangling References (opens on the source site)

In this blog post, we’ll explore ways to improve the safety of a simple configuration manager. We’ll handle common pitfalls like dangling references and excessive stack usage. Additionally, we’ll see how C++26 helps enforce safer coding practices with stricter diagnostics and improved handling of large objects. Let’s go. Step 1: The Buggy Implementation Below is a simple example of a manager object that stores various configs in a map and provides a method to retrieve them. When a requested configuration isn’t found, the code attempts to return a default certificate: #include #include…

Read at the source

8 More C++23 Examples (opens on the source site)

In this article, you’ll see eight larger examples that illustrate the changes in C++23. C++23 brings a ton of cool features, as you can see in my two previous articles (here and here). So far, we explored each new addition one by one, but I’d like to share more examples that combine multiple features. Here we go: 1. std::ranges::to<> The ranges::to<> feature allows you to convert ranges into containers easily: #include #include #include #include #include #include int main() { std::vectorint> numbers = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; std::unordered_mapint, std::string> number_to_text = { {1,…

Read at the source

Privacy choices

Reading never requires analytics. These choices last 90 days on this browser.

Essential sign-in and security storage always stays on. Read the privacy notice.