Articles & Books

Simple Compile-Time Dynamic Programming in Modern C++ -- Andrew Drakeford

logo.pngCompile time code can be very efficient. Andrew Drakeford demonstrates how to write efficient chains of matrix multiplication.

Simple Compile-Time Dynamic Programming in Modern C++

by Andrew Drakeford

From the article:

Modern C++ enables us to solve mathematical optimisation problems at compile time. With the expanded constexpr capabilities [Fertig21Turner18Turner19Wu24], we can now write clear and efficient optimisation logic that runs during compilation. Fixed-size containers such as std::array fit naturally into these routines. Even standard algorithms, such as std::sort and std::lower_bound, are now constexpr, enabling more straightforward code and more powerful compile-time computations. Additionally, compile-time optimisation generates constant results, which enables the compiler to create even more efficient code. We will use the matrix chain multiplication problem as our worked example.

Matrix chain multiplication

Matrix chain multiplication is a classic dynamic programming problem [Corman22Das19Mount]. It aims to determine the most efficient method for multiplying a sequence of matrices. Since matrix multiplication is associative, the order of grouping does not affect the result. However, the number of scalar multiplications involved can vary depending on the grouping.

Consider the three matrices A₁ (10×100), A₂ (100×5), and A₃ (5×50), multiplied in a chain, A₁ × A₂ × A₃.

There are two ways to multiply them:

  1. Grouping as (A₁ × A₂) × A₃ first computes a 10×5 matrix, then multiplies that with A₃. This results in 5,000 operations for the first multiplication, and another 2,500 for the second – a total of 7,500 scalar multiplications.
  2. Grouping as A₁ × (A₂ × A₃) first multiplies A₂ and A₃, then A₁. This results in 25,000 operations for the first step and 50,000 for the second – a total of 75,000, which is clearly worse.

C++26 reflection at compile-time -- Andreas Fertig

797f4c8c0b89b22b.pngIn today's post, I like to talk about C++26 and one of the probably most impactful features that have been added to the working draft. While C++26 is still some months away from official completion, since the WG21 summer meeting in June we all now know what will be in C++26.

C++26 reflection at compile-time

by Andreas Fertig

From the article:

While the new standard will have plenty of great improvements the one that will most likely change a lot is reflection at compile-time! In Sofia we voted seven reflection papers into C++26:

  • P1306R5 Expansion statements
  • P2996R13 Reflection for C++26
  • P3096R12Function parameter reflection in reflection for C++26
  • P3293R3Splicing a base class subobject
  • P3394R4Annotations for reflection
  • P3491R3define_static_
  • P3560R2Error handling in reflection

The papers above should give you enough to read for your vacation. I'll leave that theoretical study up to you for now.

Let's talk practical

The main question is, what can you do with that new feature? Well, I'm not the first one who published their ideas.

Format your own type (Part 2) -- Sandor Dargo

SANDOR_DARGO_ROUND.JPGPreviously, we discussed how to write our own formatter and finished with a relatively simple solution for printing a struct called ProgrammingLanguage. Today, we’ll take it to the next level.

Format your own type (Part 2)

by Sandor Dargo

From the article:

Add more options for semantic versioning

Let’s dream big. Instead of only handling major and minor versions (like Python 3.12), let’s aim to fully support semantic versioning.

Semantic versioning (SemVer) is a versioning scheme that conveys meaning about the underlying changes in a release. It typically consists of three parts: MAJOR.MINOR.PATCH.

We should be able to print all these correctly:

ProgrammingLanguage cpp{"C++", 20};
ProgrammingLanguage python312{"Python", 3, 12};
ProgrammingLanguage python31211{"Python", 3, 12, 11};


std::cout << std::format("{:%n%v} is fun", cpp) << '\n';  // C++20 is fun
std::cout << std::format("{:%n %v} is fun", python312) << '\n';  // Python 3.12 is fun
std::cout << std::format("{:%n %v} is fun", python31211) << '\n';  // Python 3.12.11 is fun

Format your own type (Part 1) -- Sandor Dargo

SANDOR_DARGO_ROUND.JPGI recently published two posts about how C++26 improves std::format and the related facilities. (If you missed them, here are Part 1 and Part 2). Now it’s time to explore how you can format your own types using std::format.

Format your own type (Part 1)

by Sandor Dargo

From the article:

std::format was introduced in C++20 and is based on Victor Zverovich’s <fmt> library, which in turn was inspired by Python’s string formatting capabilities.

Let’s skip the fancy formatting options and simply see how to interpolate values using std::format.

#include <format>
#include <iostream>
#include <string>

int main() {
    std::string language{"C++"};
    int version{20};
    std::cout << std::format("{}{} is fun", language, version) << '\n';
}

/*
C++20 is fun
*/

That was easy.

Now imagine you want to print your own type. That won’t work by default.

A Library Approach to Constant Template Parameters -- Barry Revzin

C++26 has brought big advances, especially with reflection making its way into the working draft, but one long-standing challenge remains: supporting richer class types as constant template parameters. Although the language solution isn’t here yet, we can get surprisingly far with a library approach that uses reflection and static objects to extend what’s possible today.

A Library Approach to Constant Template Parameters

by Barry Revzin

From the article:

This library achieves two things.

First, it is just, in general, very useful. I’m hoping to make it more of a Real Library™️ once Reflection gets implemented in more than just the Bloomberg fork of Clang that Dan Katz implemented.

Second, I think it demonstrates the power of Reflection. There are so many problems that were not possible in C++23 that become solvable in C++26. We’re going to spend the next several years discovering more of those, and that makes it a pretty exciting time for C++.

 

C++26: std::format improvements (Part 2) -- Sandor Dargo

SANDOR_DARGO_ROUND.JPGIn Part 1, we explored the improvements C++26 brings to std::format — from better to_string behavior to compile-time safety checks. In this part, we look at runtime formatting, defect fixes, and support for new types like std::filesystem::path.

C++26: std::format improvements (Part 2)

by Sandor Dargo 

From the article:

Runtime format strings

P2216R3 brought quite some improvements to std::format, including compile-time checking for format strings. Sadly, in use cases where format strings were only available at runtime, users had to go with the type-erased formatting version, std::vformat:

std::vformat(str, std::make_format_args(42));

Using two different APIs is not a great user experience, moreover, std::vformat was designed to be used by formatting function writers and not by end users. In addition, you might run into undefined behaviour, detailed in the next section.

To overcome this situation, P2918R2 adds std::runtime_format so you can mark format strings that are only available at run-time. As such you can opt out of compile-time format strings checks. This makes the API cleaner and the user code will read better as it shows better the intentions.

C++26: std::format improvement (Part 1) -- Sandor Dargo

SANDOR_DARGO_ROUND.JPGC++26 brings a series of improvements to std::format, continuing the work started in C++20 and refined in C++23. These changes improve formatting consistency, runtime safety, and user ergonomics. There are so many of these updates, that I decided to divide them into two articles.

C++26: std::format improvement (Part 1)

by Sandor Dargo

From the article:

Arithmetic overloads of std::to_string and std::to_wstring use std::format

P2587R3 by Victor Zverovich proposes replacing sprintf with std::format in the arithmetic overloads of std::to_string and std::to_wstring.

The motivation?

std::to_string has long been known to produce not-so-great and misleading results (differing from iostreams), especially with floating-point values. std::to_string uses the global C locale. In practice, it’s unlocalized. Also, it often places the decimal points to suboptimal places:

std::cout << std::to_string(-1e-7); // prints: -0.000000 
std::cout << std::to_string(0.42); // prints: 0.420000
These outputs are imprecise and often unnecessary. By leveraging std::format (and ultimately std::to_chars), we now get clearer, shorter representations. The representations of floating-point overloads become also unlocalized and use the shortest decimal representations.

As a result, the above outputs would change as follow:

    std::cout << std::to_string(-1e-7);  // prints: -1e-7
    std::cout << std::to_string(0.42); // prints: 0.42

Once More About dynamic_cast, a Real Use Case -- Sandor Dargo

SANDOR_DARGO_ROUND.JPGWhile dynamic_cast is often discouraged for its impact on readability and reliance on RTTI, there are rare situations where it can be the most practical and safe solution. In this post, we explore one such real-world case: using dynamic_cast for runtime versioning of plugin interfaces in a way that balances compatibility, safety, and extensibility.

Once More About dynamic_cast, a Real Use Case

by Sandor Dargo

From the article:

I wrote a couple of times about dynamic_cast and I discouraged you from using it. In general, it makes code worse in terms of readability. When you get rid of dynamic_cast, either via self-discipline or by turning RTTI off, you’ll have to rely on dynamic dispatching and better abstractions.

But there might be cases, when it’s not possible or at least it’s not meaningful to remove dynamic_cast, here is one, sent by one of you.

Versioning with the help of dynamic_cast

They have an SDK that anyone can implement. As there are new features added every now and then, the API keeps changing. Not surprisingly, the owners of the SDK want to prevent their users’ code from breaking. They achieve this by having different “versioned” interfaces for the same service where a new version inherits from the previous one.

Let’s see a simplified example.

 

Trip report: C++ On Sea 2025 -- Sandor Dargo

cpponsea2025-folkestone-to-dover.jpgAnother year, another trip report from C++ On Sea!

Trip report: C++ On Sea 2025

by Sandor Dargo

From the article:

First, a heartfelt thank-you to the organizers for inviting me to speak, and an equally big thank-you to my wife for taking care of the kids while I spent three days in Folkestone — plus a few more in London to visit the Spotify office and catch up with some bandmates.

If you have the chance, try to arrive early or stay around Folkestone for an extra day. It’s a lovely town and it’s worth exploring it. The conference program is very busy even in the evenings, so don’t count on the after hours.

This year, I arrived an half a day in advance and I had a wonderful hike from Folkestone to Dover. It was totally worth it.

In this post I’ll share:

  • Thoughts on the conference experience.
  • Highlights from talks and ideas that resonated with me.
  • Personal impressions, including reflections on my own sessions — both the main talk and the lightning talk.