<![cdata[standard C++ | Articles & Books]]> http://isocpp.org/blog en Copyright 2025 Discovering Observers - Part 3 -- Sandor Dargo https://isocpp.org//blog/2025/11/discovering-observers-part-3-sandor-dargo https://isocpp.org//blog/2025/11/discovering-observers-part-3-sandor-dargo SANDOR_DARGO_ROUND.JPGOver the last two posts, we explored different implementations of the observer pattern in C++. We began with a very simple example, then evolved toward a more flexible, template- and inheritance-based design.

This week, let’s move further — shifting away from inheritance and embracing composition.

Discovering Observers - Part 3

by Sandor Dargo

From the article:

You might say (and you’d be right) that publishers and subscribers can just as well be used as members instead of base classes. In fact, with our previous implementation, handling changes inside subscribers felt more complicated than necessary.

What we’d really like is this: subscribers that observe changes and trigger updates in their enclosing class in a coherent way. As one of the readers of Part 1 pointed out, this can be elegantly achieved if subscribers take callables.

Step 1: Subscribers with callables

We start by letting Subscriber accept a std::function, which gets called whenever the subscriber is updated:

]]>
2025年11月05日 20:17:43 +0000 Blog Staff
Why can’t std::apply figure out which overload I intend to use? -- Raymond Chen https://isocpp.org//blog/2025/10/why-cant-stdapply-figure-out-which-overload-i-intend-to-use-raymond-chen https://isocpp.org//blog/2025/10/why-cant-stdapply-figure-out-which-overload-i-intend-to-use-raymond-chen RaymondChen_5in-150x150.jpgWhen you pass an overloaded function like f to std::apply, the compiler can’t peek inside the tuple to figure out which overload matches—it only sees an ambiguous callable and a single tuple argument. Because overload resolution happens before the tuple is unpacked, you need an extra layer (like a lambda) to forward the unpacked arguments and give the compiler enough information to pick the correct overload.

Why can’t std::apply figure out which overload I intend to use? Only one of them will work!

by Raymond Chen

From the article:

Consider the following:

void f(int, int);
void f(char*, char*);

void test(std::tuple<int, int> t)
{
 std::apply(f, t); // error
}

The compiler complains that it cannot deduce the type of the first parameter.

I’m using std::apply here, but the same arguments apply to functions like std::invoke and std::bind.

From inspection, we can see that the only overload that makes sense is f(int, int) since that is the only one that accepts two integer parameters.

But the compiler doesn’t know that std::apply is going to try to invoke its first parameter with arguments provided by the second parameter. The compiler has to choose an overload based on the information it is given in the function call.

]]>
2025年10月31日 20:16:09 +0000 Blog Staff
Discovering Observers - Part 2 -- Sandor Dargo https://isocpp.org//blog/2025/10/discovering-observers-part-2-sandor-dargo https://isocpp.org//blog/2025/10/discovering-observers-part-2-sandor-dargo SANDOR_DARGO_ROUND.JPGIn the last post, we built a templated observer framework that let any publisher push strongly-typed messages to its subscribers.
This time we’ll push the design further by trying to let a single publisher handle multiple message types—and we’ll quickly see how that innocent goal invites ambiguity, boilerplate, and some surprising trade-offs.

Discovering Observers - Part 2

by Sandor Dargo

From the article:

Last week, we took the observer pattern from a very simple example and evolved it into a more flexible, template-based implementation in C++. We ended up with abstracted publishers and subscribers, a templated message type for flexibility, and publishers controlling when and how updates are pushed.

This week, we’re going to tackle the challenge of supporting multiple message types in a single publisher.

First attempt: multiple inheritance of templated bases

It’s tempting to provide different specializations for our templates so the same publisher can push different message types.

]]>
2025年10月28日 20:05:54 +0000 Blog Staff
The final schedule for Meeting C++ 2025 has been published https://isocpp.org//blog/2025/10/the-final-schedule-for-meeting-cpp-2025-has-been-published https://isocpp.org//blog/2025/10/the-final-schedule-for-meeting-cpp-2025-has-been-published With today, the final schedule for Meeting C++ 2025 has been published. Tickets for Berlin and online are still available until next week Wednesday!

The last update to the schedule for Meeting C++ 2025

by Jens Weller

From the article:

With release of the static html schedule for the website everything is ready for Meeting C++ 2025!

For a few years now Meeting C++ offers two schedules: the live schedule is coming from the database, which allows us to make changes during the conference. The other schedule is part of the static website and just a single page powered by the C++ CMS from Meeting C++. Due to the 5th track this year I've just had one week before the conference the time to update the website with this now final program for the conference.

]]>
2025年10月28日 16:43:21 +0000 Meeting C++
Looking at binary trees in C++ https://isocpp.org//blog/2025/10/looking-at-binary-trees-in-cpp https://isocpp.org//blog/2025/10/looking-at-binary-trees-in-cpp While preparing a talk for Meeting C++ 2025 I've started looking into binary trees. And got curious about a different design choice.

Looking at binary trees in C++

by Jens Weller

From the article:

I'm in the process of preparing a quick talk on trees in C++ for Meeting C++ 2025. In order to see what the web offers, I've searched exactly for this, "trees in C++".

This showed that most posts found by duckduckgo or google were about binary trees, and in particular the same or similar implementation of using raw pointers for the left/right elements in the tree. Including using new to allocate for the nodes, only some times the code also bothers with using delete. The basic node class looks like this:

]]>
2025年10月24日 15:23:21 +0000 Meeting C++
Introducing the Constexpr Debugger -- Alexander Karaev https://isocpp.org//blog/2025/10/introducing-the-constexpr-debugger-alexander-karaev https://isocpp.org//blog/2025/10/introducing-the-constexpr-debugger-alexander-karaev intro_image-1.pngThe new Constexpr Debugger available in the first CLion 2025.3 EAP build allows you to stay in the compiler’s world and see what really happens – by stepping through evaluation, inspecting values, and confirming which if constexpr branch fired. Using it helps you understand exactly what the compiler is doing and fix issues faster.

Introducing the Constexpr Debugger

by Alexander Karaev

From the article:

“Not a constant expression.” You’ve seen the diagnostics and the note trail, but never the actual state. Until now.

Modern C++ pushes more logic into constexpr/consteval: parsers, tables, DSLs, hashing – real code with real branches. When code fails at compile time, you can either try to guess the reason from the compiler’s notes or de‑constexpr it and hope the runtime reproduction matches what the compiler actually did.

The new Constexpr Debugger available in the first CLion 2025.3 EAP build allows you to stay in the compiler’s world and see what really happens – by stepping through evaluation, inspecting values, and confirming which if constexpr branch fired. Using it helps you understand exactly what the compiler is doing and fix issues faster.

]]>
2025年10月23日 20:03:17 +0000 Blog Staff
Discovering Observers - Part 1 -- Sandor Dargo https://isocpp.org//blog/2025/10/discovering-observers-part-1-sandor-dargo https://isocpp.org//blog/2025/10/discovering-observers-part-1-sandor-dargo SANDOR_DARGO_ROUND.JPGThe goal of this mini-series is to explore the Observer Design Pattern in C++, walking through different implementations and weighing their pros and cons.

Discovering Observers - Part 1

by Sandor Dargo

From the article:

First, let’s briefly recap what the observer pattern is. It belongs to the family of behavioral design patterns.

As a reminder: design patterns are usually grouped into three categories: creational, structural, and behavioral.

You might also have encountered the observer under other names such as listener, event subscriber, or publisher-subscriber.

The central idea is simple: instead of repeatedly querying an object for information, the querying object (the observer) gets notified automatically when the information holder (the subject) changes. For example, imagine an orchestrator object that needs the latest value of a user setting. Instead of polling the setting every n milliseconds, it can subscribe to value changes and receive notifications whenever a new value is set.

Using the common terminology: there is typically one publisher and one or more subscribers. Subscribers register for events or changes, and whenever an update happens, the publisher notifies them.

]]>
2025年10月18日 20:15:41 +0000 Blog Staff
Trip Report: CppCon 2025 -- Sandor Dargo https://isocpp.org//blog/2025/10/trip-report-cppcon-2025-sandor-dargo https://isocpp.org//blog/2025/10/trip-report-cppcon-2025-sandor-dargo bjarne-rock-cppcon2025.jpgA long-delayed dream finally came true: after years of near-misses and lessons learned (“better to be invited than sent”), I made it to CppCon—and it was bigger, louder, and more inspiring than I imagined. In this recap I share the vibe of the week, five standout talks and ideas, a few notes from my own session, and links to recordings as they appear.

Trip Report: CppCon 2025

by Sandor Dargo

From the article:

CppCon is simply bigger than any other C++ conference I’ve attended. A massive venue packed with people and sponsors. I logged more than 10,000 steps on the very first day — without ever leaving the resort or going to the gym.

The whole experience felt like it was on another scale compared to European conferences (which I also love). But then again, that’s often the impression when you see something American from a European perspective, isn’t it?

I never would have imagined a C++ conference where a live band plays while Bjarne Stroustrup himself makes final checks before stepping on stage to deliver the opening keynote. Absolutely rocks.

]]>
2025年10月14日 20:11:13 +0000 Blog Staff
Structured Bindings in C++17, 8 Years Later -- Bartlomiej Filipek https://isocpp.org//blog/2025/10/structured-bindings-in-cpp17-8-years-later-bartlomiej-filipek https://isocpp.org//blog/2025/10/structured-bindings-in-cpp17-8-years-later-bartlomiej-filipek Filipek-structuredbindings.pngStructured 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.

Structured bindings in C++17, 8 years later

by Bartlomiej Filipek

From the article:

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 <const Key, ValueType>.

Now, when you iterate through elements, you can do:

for (const auto& elem : myMap) { ... } 

You need to write elem.first and elem.second to refer to the key and the value.

std::map<KeyType, ValueType> myMap = getMap(); 
// C++14: 
for (const auto& elem : myMap) { 
 // elem.first - is the key 
 // elem.second - is the value 
}
]]>
2025年10月09日 19:43:16 +0000 Blog Staff
You should use QPainterPath they said... https://isocpp.org//blog/2025/10/you-should-use-qpainterpath-they-said https://isocpp.org//blog/2025/10/you-should-use-qpainterpath-they-said A blog entry about this years t-shirt at Meeting C++ 2025 and exploring QPainterPath for it.

You should use QPainterPath they said...

by Jens Weller

From the article:

This post is about what I learned while playing around with QPainterPath for this years t-shirt at Meeting C++ 2025 sponsored by Hudson River Trading.

One of the issues from last years t-shirt was when using drawText from QPainter, one does not really *draw* text in an svg exported. Instead you'll get the text and the font kinda embedded in an svg. What good is that in a vector graphic? This was a bit of a surprise when I ran into issues with this last year during printing. While this could be solved with the printing company picking a different font, it would have been also solved by using QPainterPath. At least this was the feedback from some of the Qt experts present onsite or online...

]]>
2025年10月08日 17:22:39 +0000 Meeting C++
How to Look up Values in a Map -- Sandor Dargo https://isocpp.org//blog/2025/10/how-to-look-up-values-in-a-map-sandor-dargo https://isocpp.org//blog/2025/10/how-to-look-up-values-in-a-map-sandor-dargo SANDOR_DARGO_ROUND.JPGWhether you’re in a coding interview or writing production code, you’ll eventually face the question: What’s the right way to look up values in a std::map or std::unordered_map? For simplicity, we’ll refer to both containers as maps in this post.

How to Look up Values in a Map

by Sandor Dargo

From the article:

Let’s explore the different options — along with their pros and cons.

operator[]

Using operator[] is the old-fashioned way to access elements of a map. It takes a key and returns a reference to the corresponding value. The complexity is log(n) for std::map and average constant time (with worst-case linear) for std::unordered_map.

However, there’s a big caveat.

What if the key is not present in the map?

Unlike a vector — where accessing an invalid index with operator[] leads to undefined behavior — a map will instead insert a new entry with the given key and a default-constructed value. This side effect makes operator[] unsafe for lookups where insertion is not desired.

]]>
2025年10月01日 19:39:59 +0000 Blog Staff
Safely passing strings and string_views -- Niek J Bouman https://isocpp.org//blog/2025/09/safely-passing-strings-and-string_views https://isocpp.org//blog/2025/09/safely-passing-strings-and-string_views Passing a string temporary into a string_view can make the latter dangling

Safely passing std::strings and std::string_view

by Niek J Bouman

From the article:

Many of you will agree that C++ is a language that comes with sharp edges. One example is `std::string_view`; introduced as a type to prevent unnecessary std::string-copies, but it introduces a new footgun, namely when passing a temporary string into it:

]]>
2025年9月27日 21:01:08 +0000 niekb
A safer C++ pointer class -- Niek J. Bouman https://isocpp.org//blog/2025/09/a-safer-cpp-pointer-class-niek-bouman https://isocpp.org//blog/2025/09/a-safer-cpp-pointer-class-niek-bouman Sometimes some object A needs to interact with another object B, e.g., A calls one of B’s methods. In a language like C++, it is left to the programmer to assure that B outlives A; if B happens to be already destructed, this would be a use-after-free bug. Managing object lifetimes can be tricky, especially with asynchronous code.

A safe pointer in C++ that protects against use after free and updates when the pointee is moved

by Niek J. Bouman

From the article:

We propose a design for a safe pointer to an object of type T that is weak in that it does not have ownership semantics, and gets notified in case the pointee is either destructed or moved.

We will pay a price at runtime for these extra guarantees in terms of a small heap-allocated state, a double pointer indirection when accessing the pointee (comparable to a virtual function call), and a check against nullptr.

The main idea of our design is to internally use a std::shared_ptr<T*> to share ownership of a (heap-allocated) pointer T*. The ownership is shared by the pointee and all safe_ptr<T> instances. The pointee type T must derive from the base class safe_ptr_factory (templated on T, using the Curiously Recurring Template Pattern) with a destructor that automatically notifies the shared state about destruction by setting T* to nullptr, and with a move constructor and move assignment operator that update T* to the new this pointer (which we must properly cast with static_cast<T*>). The double indirection thus comes from having to dereference the shared_ptr to obtain an ordinary pointer T*, after which you must dereference once more to access the pointee. You might recognize an instance of Gang-of-Four’s observer pattern in our design.

]]>
2025年9月27日 20:59:03 +0000 niekb
Linus Torvalds and the Supposedly Garbage Code -- Giovanni Dicanio https://isocpp.org//blog/2025/09/linus-torvalds-and-the-supposedly-garbage-code-giovanni-dicanio https://isocpp.org//blog/2025/09/linus-torvalds-and-the-supposedly-garbage-code-giovanni-dicanio Some reflections on a harsh critic by Linus Torvalds on a RISC-V Linux kernel contribution.

Linus Torvalds and the Supposedly “Garbage Code”

by Giovanni Dicanio

From the article:

So, the correct explicit code is not something as simple as “(a << 16) + b”.

[...] As you can see, the type casts, the parentheses, the potential bit-masking, do require attention. But once you get the code right, you can safely and conveniently reuse it every time you need!

]]>
2025年9月27日 20:54:24 +0000 Giovanni Dicanio
CppCon 2025 Trip Report – tipi.build by EngFlow https://isocpp.org//blog/2025/09/cppcon-2025-trip-report-tipi.build-by-engflow https://isocpp.org//blog/2025/09/cppcon-2025-trip-report-tipi.build-by-engflow CppCon 2025 was packed with exciting talks, deep dives, and great conversations.

CppCon 2025 Trip Report

by tipi.build by EngFlow

About the report

tipi.build by EngFlow attended both as a developer team and as a CppCon sponsor. Discover in our trip report the highlights from the sessions we attended and the talks we gave, How monday’s afternoon break started with ice cream + key takeaways and resources if you’d like to dive deeper.

]]>
2025年9月27日 20:50:20 +0000 daminetreg
C++26: Concept and variable-template template-parameters -- Sandor Dargo https://isocpp.org//blog/2025/09/cpp26-concept-and-variable-template-template-parameters-sandor-dargo https://isocpp.org//blog/2025/09/cpp26-concept-and-variable-template-template-parameters-sandor-dargo SANDOR_DARGO_ROUND.JPGLast week, we discussed why we should sometimes use remove_cvref_t on our template parameters before applying concepts to them. We also saw that the solution is not super readable because we lose access to the terse, shorthand syntax.

C++26: Concept and variable-template template-parameters

by Sandor Dargo

From the article:

C++ already allows passing templates as template parameters, but only if they are class templates. A common reason for doing this is to allow higher-level abstractions. For instance, you may want to pass in a container template like std::vector, without specifying the type it contains.

Jason Turner explains this well in C++ Weekly - Ep 368 - The Power of template-template Parameters: A Basic Guide, but here’s his example for quick reference:

template<template <typename Contained, typename Alloc = std::allocator<Contained>>
		 typename ResultType>
auto get_data() {
	ResultType<double> result;
	// ...
	return result;
}

int main() {
	auto data = get_data<std::vector>();
}
]]>
2025年9月25日 22:20:21 +0000 Blog Staff
Use concepts with std::remove_cvref_t -- Sandor Dargo https://isocpp.org//blog/2025/09/use-concepts-with-stdremove-cvref-t-sandor-dargo https://isocpp.org//blog/2025/09/use-concepts-with-stdremove-cvref-t-sandor-dargo SANDOR_DARGO_ROUND.JPGLet’s talk about templates, constraints, and concepts. We’ll start with a quick reminder of why concepts are essential when working with templates. Then we’ll dive into the challenge posed by reference-qualified types and finish with a practical solution.

Use concepts with std::remove_cvref_t

by Sandor Dargo

From the article:

By now, it’s well known that using unconstrained templates is discouraged. Even the C++ Core Guidelines strongly recommend against it.

T.47 only advises avoiding highly visible unconstrained templates with common names due to the risks of argument-dependent lookup going wrong. T.10 goes further, recommending that we specify concepts for every template argument to improve both simplicity and readability.

The same idea appears in I.9, which suggests documenting template parameters using concepts.

It’s hard to argue with these guidelines. Concepts make code more readable — just by looking at a function, class, or variable template, the reader can immediately tell what kinds of types are accepted.

If you want to learn more about concepts, check out my concepts-related articles or my book on concepts.

But what makes a good concept? That’s a more complex topic — and one we can’t fully cover in a single article.

]]>
2025年9月23日 22:17:57 +0000 Blog Staff
Simple Compile-Time Dynamic Programming in Modern C++ -- Andrew Drakeford https://isocpp.org//blog/2025/09/simple-compile-time-dynamic-programming-in-modern-cpp-andrew-drakeford https://isocpp.org//blog/2025/09/simple-compile-time-dynamic-programming-in-modern-cpp-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 [Fertig21, Turner18, Turner19, Wu24], 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 [Corman22, Das19, Mount]. 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.
]]>
2025年9月19日 22:15:15 +0000 Blog Staff
C++26 reflection at compile-time -- Andreas Fertig https://isocpp.org//blog/2025/09/cpp26-reflection-at-compile-time-andreas-fertig https://isocpp.org//blog/2025/09/cpp26-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
  • P3096R12: Function parameter reflection in reflection for C++26
  • P3293R3: Splicing a base class subobject
  • P3394R4: Annotations for reflection
  • P3491R3: define_static_
  • P3560R2: Error 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.

]]>
2025年9月17日 22:10:14 +0000 Blog Staff
Format your own type (Part 2) -- Sandor Dargo https://isocpp.org//blog/2025/09/format-your-own-type-part-2-sandor-dargo https://isocpp.org//blog/2025/09/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
]]>
2025年9月15日 22:07:32 +0000 Blog Staff
Format your own type (Part 1) -- Sandor Dargo https://isocpp.org//blog/2025/09/format-your-own-type-part-1-sandor-dargo https://isocpp.org//blog/2025/09/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.

]]>
2025年9月11日 03:02:43 +0000 Blog Staff
A Library Approach to Constant Template Parameters -- Barry Revzin https://isocpp.org//blog/2025/09/a-library-approach-to-constant-template-parameters-barry-revzin https://isocpp.org//blog/2025/09/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++.

]]>
2025年9月04日 21:56:05 +0000 Blog Staff
C++26: std::format improvements (Part 2) -- Sandor Dargo https://isocpp.org//blog/2025/09/cpp26-stdformat-improvements-part-2-sandor-dargo https://isocpp.org//blog/2025/09/cpp26-stdformat-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.

]]>
2025年9月02日 21:55:00 +0000 Blog Staff
C++26: std::format improvement (Part 1) -- Sandor Dargo https://isocpp.org//blog/2025/08/cpp26-stdformat-improvement-part-1-sandor-dargo https://isocpp.org//blog/2025/08/cpp26-stdformat-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
]]>
2025年8月29日 21:55:35 +0000 Blog Staff
Boost version 1.89 released! https://isocpp.org//blog/2025/08/boost-version-1.89-released https://isocpp.org//blog/2025/08/boost-version-1.89-released space.pngspace.pnggetboost.pngRelease 1.89 of the Boost C++ Libraries is now available.

One new library and updates to 28 more.

Bloom, configurable filters for probabilistic lookup: https://boost.org/libs/bloom

]]>
2025年8月27日 21:51:14 +0000 Blog Staff
Once More About dynamic_cast, a Real Use Case -- Sandor Dargo https://isocpp.org//blog/2025/08/once-more-about-dynamic-cast-a-real-use-case-sandor-dargo https://isocpp.org//blog/2025/08/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.

]]>
2025年8月21日 15:14:18 +0000 Blog Staff
Trip report: C++ On Sea 2025 -- Sandor Dargo https://isocpp.org//blog/2025/08/trip-report-cpp-on-sea-2025-sandor-dargo https://isocpp.org//blog/2025/08/trip-report-cpp-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.
]]>
2025年8月19日 14:11:51 +0000 Blog Staff
A virtual destructor in C++, when? -- Andreas Fertig https://isocpp.org//blog/2025/08/a-virtual-destructor-in-cpp-when-andreas-fertig https://isocpp.org//blog/2025/08/a-virtual-destructor-in-cpp-when-andreas-fertig 2025年07月01日-when-to-not-use-a-virtual-dtor-tw.pngWhen should a destructor be virtual in C++? In this post, we’ll explore a real-world example from smart pointer implementation to illustrate when virtual destructors are necessary — and when they’re not.

A virtual destructor in C++, when?

by Andreas Fertig

From the article:

In today's post, I would like to explain a design rationale used in my post Understanding the inner workings of C++ smart pointers - The shared_ptr.

Keen readers spotted that in my implementation of ctrl_blk_base, I didn't make the destructor virtual. Here is the original code for easy reference:


]]>
2025年8月15日 15:05:43 +0000 Blog Staff
Reflecting JSON into C++ Objects -- Barry Revzin https://isocpp.org//blog/2025/08/reflecting-json-into-cpp-objects-barry-revzin https://isocpp.org//blog/2025/08/reflecting-json-into-cpp-objects-barry-revzin C++26 marks a transformative milestone with the adoption of full compile-time reflection, enabling powerful new metaprogramming capabilities. In this post, we’ll explore how reflection lets you turn a JSON file directly into a fully-typed C++ object — all at compile time.

Reflecting JSON into C++ Objects

by Barry Revzin

From the article:

Last week, C++26 was finalized in Sofia, Bulgaria — and C++26 will include all of the reflection papers that we were pushing for:

  1. P2996R13: Reflection for C++26
  2. P3394R4: Annotations for Reflection
  3. P3293R3: Splicing a Base Class Subobject
  4. P3491R3: define_static_{string,object,array}
  5. P1306R5: Expansion Statements
  6. P3096R12: Function Parameter Reflection in Reflection for C++26
  7. P3560R2: Error Handling in Reflection

Those are in the order in which they were adopted, not in the order of their impact (otherwise splicing base classes would go last). This is a pretty incredible achievement that couldn’t have happened without lots of people’s work, but no one person is more responsible for Reflection in C++26 than Dan Katz.

So today I wanted to talk about a very cool example that Dan put together on the flight home from Sofia, while I was unconscious a few seats over: the ability to, at compile time, ingest a JSON file and turn it into a C++ object. That is, given a file test.json that looks like this:

{ "outer": "text", 
"inner": { "field": "yes", "number": 2996 } 
} 

We can write this:

constexpr const char data[] = { 
 #embed "test.json" 
 , 0 

}; constexpr auto v = json_to_object<data>;
]]>
2025年8月13日 16:00:45 +0000 Blog Staff
Discover C++26’s Compile-Time Reflection -- Daniel Lemire https://isocpp.org//blog/2025/08/discover-cpp26s-compile-time-reflection-daniel-lemire https://isocpp.org//blog/2025/08/discover-cpp26s-compile-time-reflection-daniel-lemire Capture-decran-le-2025年06月21日-a-21.55.10-825x510.pngC++26 is bringing a long-awaited feature to the language: compile-time reflection, enabling programs to introspect and manipulate their own structure during compilation. This powerful capability opens the door to eliminating boilerplate, improving performance, and writing more expressive, reusable code with ease.

Discover C++26’s Compile-Time Reflection

by Daniel Lemire

From the article:

Herb Sutter just announced that the verdict is in: C++26, the next version of C++, will include compile-time reflection.

Reflection in programming languages means that you have access the code’s own structure. For example, you can take a class, and enumerate its methods. For example, you could receive a class, check whether it contains a method that returns a string, call this method and get the string. Most programming languages have some form of reflection. For example, the good old Java does have complete reflection support.

However, C++ is getting compile-time reflection. It is an important development.

I announced a few months ago that thanks to joint work with Francisco Geiman Thiesen, the performance-oriented JSON library simdjson would support compile-time reflection as soon as mainstream compilers support it.

]]>
2025年8月09日 16:54:09 +0000 Blog Staff
Variadic Class Template Arguments -- Sandor Dargo https://isocpp.org//blog/2025/08/variadic-class-template-arguments-sandor-dargo https://isocpp.org//blog/2025/08/variadic-class-template-arguments-sandor-dargo SANDOR_DARGO_ROUND.JPGVariadic templates are a powerful C++ feature that allow template classes or functions to accept an arbitrary number of parameters. In this article, we’ll explore how to combine them with class templates and examine the various ways the parameter pack can be expanded.

Variadic Class Template Arguments

by Sandor Dargo

From the article:

Let’s talk about class templates and variadic parameters. How to use them in combination?

But first of all, what are variadic templates?

Variadic template don’t accept a fixed size of parameters, but anything from one to more. The set of parameters is called the parameter pack.

In the template parameter list, we can see the three dots (...) signaling the pack after the typename or class keywords, or after the constraints. Then later in the function / constructor parameter list, you can observe it right after the actual type name, and finally once the pack is expanded, it comes after the packed variable name.

Variadic arguments can be used in so many different ways both with function and class templates. Today, we are focusing on class templates.

When you are using variadic templates with class templates, the expansion can happen at different places. You might expand the parameter pack

  • within the constructor or any other member function
  • when declaring a member variable
  • at the inheritance list
  • in a using declaration
  • in friend declarations
]]>
2025年8月05日 15:50:40 +0000 Blog Staff
C++26: Disallow Binding a Returned Reference to a Temporary -- Sandor Dargo https://isocpp.org//blog/2025/07/cpp26-disallow-binding-a-returned-reference-to-a-temporary-sandor-dargo https://isocpp.org//blog/2025/07/cpp26-disallow-binding-a-returned-reference-to-a-temporary-sandor-dargo SANDOR_DARGO_ROUND.JPGThis change in C++26 tightens the rules around returning references to temporaries — and that’s a good thing. It turns dangerous, bug-prone code into immediate compilation errors, making code safer and easier to reason about. It also reflects a broader trend in modern C++: giving programmers stronger guarantees and better diagnostics, even at the cost of breaking some old patterns.

C++26: Disallow Binding a Returned Reference to a Temporary

by Sandor Dargo

From the article:

In short, thanks to P2748R5 by Brian Bi, it’s no longer possible to return a reference that binds to a temporary expression, and that’s just lovely.

What exactly is changing?

Often, a proposal modifies a lot of wording, and it’s not practical to start by reading through it all. But in this case, the changes are small and easy to digest, so let’s dive in.

This line is being removed:

“The lifetime of a temporary bound to the returned value in a function return statement (8.7.4) is not extended; the temporary is destroyed at the end of the full-expression in the return statement.”

And this line is being added (excluding the examples we’ll discuss in a moment):

“In a function whose return type is a reference, other than an invented function for std::is_convertible ([meta.rel]), a return statement that binds the returned reference to a temporary expression ([class.temporary]) is ill-formed.”

There are two interesting shifts here:

  • The language becomes more specific. It doesn’t merely mention “temporaries” but refers directly to references binding to temporary expressions, with certain exceptions.
  • The effect isn’t just that lifetime extension doesn’t happen, it’s now a compilation error. The code is ill-formed.
]]>
2025年7月25日 21:58:23 +0000 Blog Staff
constexpr Functions: Optimization vs Guarantee -- Andreas Fertig https://isocpp.org//blog/2025/07/constexpr-functions-optimization-vs-guarantee-andreas-fertig1 https://isocpp.org//blog/2025/07/constexpr-functions-optimization-vs-guarantee-andreas-fertig1 me.pngConstexpr has been around for a while now, but many don’t fully understand its subtleties. Andreas Fertig explores its use and when a constexpr expression might not be evaluated at compile time.

constexpr Functions: Optimization vs Guarantee

by Andreas Fertig

From the article:

The feature of constant evaluation is nothing new in 2023. You have constexpr available since C++11. Yet, in many of my classes, I see that people still struggle with constexpr functions. Let me shed some light on them.

What you get is not what you see

One thing, which is a feature, is that constexpr functions can be evaluated at compile-time, but they can run at run-time as well. That evaluation at compile-time requires all values known at compile-time is reasonable. But I often see that the assumption is once all values for a constexpr function are known at compile-time, the function will be evaluated at compile-time.

I can say that I find this assumption reasonable, and discovering the truth isn’t easy. Let’s consider an example (Listing 1).

constexpr auto Fun(int v)
{
 return 42 / v; ①
}

int main()
{
 const auto f = Fun(6); ②
 return f; ③
}
The constexpr function Fun divides 42 by a value provided by the parameter v ①. In ②, I call Fun with the value 6 and assign the result to the variable f.
]]>
2025年7月23日 21:54:53 +0000 Blog Staff
Three types of name lookups in C++ -- Sandor Dargo https://isocpp.org//blog/2025/07/three-types-of-name-lookups-in-cpp-sandor-dargo https://isocpp.org//blog/2025/07/three-types-of-name-lookups-in-cpp-sandor-dargo SANDOR_DARGO_ROUND.JPGLet's revisit a core concept in C++: how the compiler finds the names you use in your code. From qualified and unqualified name lookups to the special case of Argument-Dependent Lookup (ADL), understanding these mechanisms is essential for writing clear and correct C++ programs.

Three types of name lookups in C++

by Sandor Dargo

From the article:

Let’s get back to some basics this week and talk about name lookups in C++. In other words: when you refer to a symbol in your code, how does the compiler find it?

Essentially, we can differentiate between three kinds of lookups:

  • Qualified name lookup
  • Unqualified name lookup
  • Argument-Dependent Lookup (ADL)

Let’s explore them in that order.

Qualified Name Lookup

The term qualified refers to symbols that are explicitly scoped using the :: operator. In other words, these are names that appear to the right of a ::, such as x in a::b::x.

Before the compiler can perform a qualified name lookup, it must first resolve the left-hand side of the :: operator. This identifies the namespace or class being referenced.

Qualified name lookup is relatively simple: it only searches the explicitly named scope. It does not search enclosing or outer scopes.

]]>
2025年7月21日 21:51:07 +0000 Blog Staff
Why does C++ think my class is copy-constructible when it can’t be copy-constructed? -- Raymond Chen https://isocpp.org//blog/2025/07/why-does-cpp-think-my-class-is-copy-constructible-when-it-cant-be-copy-cons https://isocpp.org//blog/2025/07/why-does-cpp-think-my-class-is-copy-constructible-when-it-cant-be-copy-cons RaymondChen_5in-150x150.jpgIn C++, the presence of a user-declared (but not explicitly deleted) copy constructor is enough for the type to be considered copy-constructible by traits like std::is_copy_constructible. However, whether that constructor is instantiable is a separate matter—if it attempts to call a deleted base copy constructor, you'll still get a compile-time error when you actually try to use it.

Why does C++ think my class is copy-constructible when it can’t be copy-constructed?

by Raymond Chen

From the article:

Consider the following scenario:

template<typename T>
struct Base
{
// Default-constructible
Base() = default;

// Not copy-constructible
Base(Base const &) = delete;
};

template<typename T>
struct Derived : Base<T>
{
Derived() = default;
Derived(Derived const& d) : Base<T>(d) {}
};

// This assertion passes?
static_assert(
std::is_copy_constructible_v<Derived<int>>);

Why does this assertion pass? It is plainly evident that you cannot copy a Derived<int> because doing so will try to copy the Base<int>, which is not copyable.

]]>
2025年7月17日 21:48:04 +0000 Blog Staff
Returning several values from a function in C++ (C++23 edition) -- Daniel Lemire https://isocpp.org//blog/2025/07/returning-several-values-from-a-function-in-cpp-c23-edition-daniel-lemire https://isocpp.org//blog/2025/07/returning-several-values-from-a-function-in-cpp-c23-edition-daniel-lemire RkWx2Fr8_400x400.jpgWhile C++ doesn’t have native syntax for returning multiple values like some other languages, modern C++ offers powerful tools to accomplish the same goal. With features like std::tuple, structured bindings, std::expected, and std::optional, handling multiple return values—and even error codes—has become both clean and expressive.

Returning several values from a function in C++ (C++23 edition)

by Daniel Lemire

From the article:

Many programming languages such as the Go programming language are designed to make it easy to return several values at once from a function. In Go, it is often used to return an optional error code. The C++ programming language does not have a built-in support for returning several values. However, several standard types can serve the same purpose. If you need to return two values, you can use an std::pair instance. If you need to return two or more values, an std::tuple instance will do. With recent C++ standards, it works really well!

Suppose we want to compute a division with a string error message when one is trying to divided by zero:

std::tuple<int,std::string> divide(int a, int b) {
 if (b == 0) {
 return {0, "Error: Division by zero"};
 }
 return {a / b, "Success"};
}

This approach works nicely. The code is clear and readable.

You might be concerned that we are fixing the type (int). If you want to write one function for all integer types, you can do so with concepts, like so:

]]>
2025年7月15日 21:44:07 +0000 Blog Staff
Constructing Containers from Ranges in C++23 -- Sandor Dargo https://isocpp.org//blog/2025/07/constructing-containers-from-ranges-in-cpp23-sandor-dargo https://isocpp.org//blog/2025/07/constructing-containers-from-ranges-in-cpp23-sandor-dargo SANDOR_DARGO_ROUND.JPGStarting from C++23, standard containers support a new set of constructor overloads. These constructors take a std::from_range tag, a range and an optional allocator. These from_range constructors make it easier to construct containers from ranges, helping make C++ code more concise, more expressive, and less error-prone.

Constructing Containers from Ranges in C++23

by Sandor Dargo

From the article:

I’ve written plenty on this blog about standard algorithms, but far less about ranges. That’s mostly because, although I’ve had production-ready compilers with C++20 ranges since late 2021, the original ranges library lacked a few key capabilities.

The biggest gap was at the end of a pipeline: you could transform data lazily, but you couldn’t drop the result straight into a brand-new container. What you got back was a view; turning that view into, say, a std::vector still required the old iterator-pair constructor.

C++23 fixes that in two complementary ways:

  • std::to (an adaptor that finishes a pipeline by converting to a container), and
  • from_range constructors on every standard container.

Today we’ll focus on the second improvement, because it’s the one you can implement in your own types, too.

The from_range constructor

Every standard container now supports a new set of constructors that make integration with ranges smoother — the so-called from_range constructors.

These constructors allow you to build a container directly from a range, rather than from a pair of iterators.

]]>
2025年7月11日 21:38:53 +0000 Blog Staff
C++ Insights now uses Clang 20 -- Andreas Fertig https://isocpp.org//blog/2025/07/cpp-insights-now-uses-clang-20-andreas-fertig https://isocpp.org//blog/2025/07/cpp-insights-now-uses-clang-20-andreas-fertig me.pngTime flies—C++ Insights just turned 7! To celebrate, I’ve upgraded the tool to Clang 20, unlocking even more C++23 and C++26 features for you to explore.

C++ Insights now uses Clang 20

by Andreas Fertig

From the article:

size_t

For a long time now, when you used size_t or std::size_t the resulting transformation kept the name. It did not expand to the underlying machine-specific date type. To be honest, that was more like a happy accident. Clang 20 came with two changes to libc++

The first https://github.com/llvm/llvm-project/commit/d6832a611a7c4ec36f08b1cfe9af850dad32da2e modularized <cstddef> for better internal structuring, avoiding too much content to be included. This patch was followed by a second one: https://github.com/llvm/llvm-project/commit/5acc4a3dc0e2145d2bfef47f1543bb291c2b866a. This one now made an interesting change.

Previously, libc++ defined std::size_t as

1
using ::size_t _LIBCPP_USING_IF_EXISTS; 

As the second patch highlighted, this required including the operating systems <stddef.h>. In the spirit of reducing unnecessary includes the line was changed to:

1
using size_t = decltype(sizeof(int)); 

This is an easy C++ solution to get the proper data type for size_t. Which is great. Yet, the AST nodes of the two versions look different. Previously, the operating system (macOS in this case) defined in its header:

1
typedef unsigned long size_t; 

Well, with the new version, the transformation no longer stops at size_t but expands it all down to unsigned long. This probably should have been the case from the beginning, but I liked that tests and transformations did not change across platforms in this specific case. However, there are other instances where the transformation did yield different output on different platforms, so I accept this one.

]]>
2025年7月09日 21:35:32 +0000 Blog Staff
What’s New for C++ Developers in Visual Studio 2022 17.14 -- Sy Brand https://isocpp.org//blog/2025/07/whats-new-for-cpp-developers-in-visual-studio-2022-17.14-sy-brand https://isocpp.org//blog/2025/07/whats-new-for-cpp-developers-in-visual-studio-2022-17.14-sy-brand RE1Mu3b.pngVisual Studio 2022 version 17.14 is now generally available! This post summarizes the new features you can find in this release for C++. You can download Visual Studio 2022 from the Visual Studio downloads page or upgrade your existing installation by following the Update Visual Studio Learn page.

What’s New for C++ Developers in Visual Studio 2022 17.14

by Sy Brand

From the article:

We’ve made a myriad of fixes and improvements to the MSVC compiler and standard library. See C++ Language Updates in MSVC in Visual Studio 2022 17.14 for a full list of changes on the compiler side, and the STL Changelog for all the standard library updates.

Compiler

We’ve added support for several C++23 features, which are available under the /std:c++latest and /std:c++23preview flags.

You can now omit () in some forms of lambdas that previously required them, thanks to P1102R2:

auto lambda = [] constexpr { }; //no '()' needed after the capture list
We implemented if consteval , with which you can run different code depending on whether the statement is executed at compile time or run time. This is useful for cases where your run time version can be heavily optimized with compiler intrinsics or inline assembly that are not available at compile time:
constexpr size_t strlen(char const* s) {
if consteval {
// if executed at compile time, use a constexpr-friendly algorithm
for (const char *p = s; ; ++p) {
if (*p == '0円') {
return static_cast<std::size_t>(p - s);
}
}
} else {
// if executed at run time, use inline assembly
__asm__("SSE 4.2 magic");
}
}
]]>
2025年7月07日 21:32:18 +0000 Blog Staff
C++26: Erroneous Behaviour -- Sandor Dargo https://isocpp.org//blog/2025/07/cpp26-erroneous-behaviour-sandor-dargo2 https://isocpp.org//blog/2025/07/cpp26-erroneous-behaviour-sandor-dargo2 logo.pngC++’s undefined behaviour impacts safety. Sandor Dargo explains how and why uninitialised reads will become erroneous behaviour in C++26, rather than being undefined behaviour.

C++26: Erroneous Behaviour

by Sandor Dargo

From the article:

If you pick a random talk at a C++ conference these days, there is a fair chance that the speaker will mention safety at least a couple of times. It’s probably fine like that. The committee and the community must think about improving both the safety situation and the reputation of C++.

If you follow what’s going on in this space, you are probably aware that people have different perspectives on safety. I think almost everybody finds it important, but they would solve the problem in their own way.

A big source of issues is certain manifestations of undefined behaviour. It affects both the safety and the stability of software. I remember that a few years ago when I was working on some services which had to support a 10× growth, one of the important points was to eliminate undefined behaviour as much as possible. One main point for us was to remove uninitialized variables which often lead to crashing services.

Thanks to P2795R5 by Thomas Köppe, uninitialized reads won’t be undefined behaviour anymore – starting from C++26. Instead, they will get a new behaviour called ‘erroneous behaviour’.

The great advantage of erroneous behaviour is that it will work just by recompiling existing code. It will diagnose where you forgot to initialize variables. You don’t have to systematically go through your code and let’s say declare everything as auto to make sure that every variable has an initialized value. Which you probably wouldn’t do anyway.

]]>
2025年7月03日 21:30:04 +0000 Blog Staff
Writing Senders -- Lucian Radu Teodorescu https://isocpp.org//blog/2025/07/writing-senders-lucian-radu-teodorescu1 https://isocpp.org//blog/2025/07/writing-senders-lucian-radu-teodorescu1 logo.pngSenders/receivers can be used to introduce concurrency. Lucian Radu Teodorescu describes how to implement senders.

Writing Senders

by Lucian Radu Teodorescu

From the article:

If people are just using frameworks based on std::execution, they mainly need to care about senders and schedulers. These are user-facing concepts. However, if people want to implement sender-ready abstractions, they also need to consider receivers and operation states – these are implementer-side concepts. As this article mainly focuses on the implementation of sender abstractions, we need to discuss these two concepts in more detail.

A receiver is defined in P2300 as “a callback that supports more than one channel” [P2300R10]. The proposal defines a concept for a receiver, unsurprisingly called receiver. To model this concept, a type needs to meet the following conditions:

  • It must be movable and copyable.
  • It must have an inner type alias named receiver_concept that is equal to receiver_t (or a derived type).
  • std::execution::get_env() must be callable on an object of this type (to retrieve the environment of the receiver).

A receiver is the object that receives the sender’s completion signal, i.e., one of set_value(), set_error(), or set_stopped(). As explained in the December 2024 issue [Teodorescu24], a sender may have different value completion types and different error completion types. For example, the same sender might sometimes complete with set_value(int, int), sometimes with set_value(double), sometimes with set_error(std::exception_ptr), sometimes with set_error(std::error_code), and sometimes with set_stopped(). This implies that a receiver must also be able to accept multiple types of completion signals.

]]>
2025年7月01日 21:27:49 +0000 Blog Staff
C++26: constexpr Exceptions -- Sandor Dargo https://isocpp.org//blog/2025/06/cpp26-constexpr-exceptions-sandor-dargo https://isocpp.org//blog/2025/06/cpp26-constexpr-exceptions-sandor-dargo In recent weeks, we’ve explored language features and library features becoming constexpr in C++26. Those articles weren’t exhaustive — I deliberately left out one major topic: exceptions.

SANDOR_DARGO_ROUND.JPGStarting with C++26, it will become possible to throw exceptions during constant evaluation. This capability is enabled through both language and library changes. Given the significance of this feature, it deserves its own dedicated post.

C++26: constexpr Exceptions

by Sandor Dargo

From the article:

P3068R6: Allowing exception throwing in constant-evaluation

The proposal for static reflection suggested allowing exceptions in constant-evaluated code, and P3068R6 brings that feature to life.

constexpr exceptions are conceptually similar to constexpr allocations. Just as a constexpr string can’t escape constant evaluation and reach runtime, constexpr exceptions also have to remain within compile-time code.

Previously, using throw in a constexpr context caused a compilation error. With C++26, such code can now compile — unless an exception is actually thrown and left uncaught, in which case a compile-time error is still issued. But the error now provides more meaningful diagnostics.

]]>
2025年6月27日 21:08:51 +0000 Blog Staff
An option(al) to surprise you -- Andreas Fertig https://isocpp.org//blog/2025/06/an-optional-to-surprise-you-andreas-fertig https://isocpp.org//blog/2025/06/an-optional-to-surprise-you-andreas-fertig me.pngIn today's post I share a learning of a customer with you. A while back, a customer asked me to join a debugging session. They had an issue they didn't (fully) understand.

An option(al) to surprise you

by Andreas Fertig

From the article:

The base

What I will show you is a much down-stripped and, of course, altered version. It was about a message system, but that's not important. Have a look at the code below.

2025年05月09日_14-05-45.png

You can see a class enum for a state and a function Worker. The function takes a State and a const char* message named data. The function's job is to create a std::optional containing the user data, a C-style string.
]]>
2025年6月25日 21:02:59 +0000 Blog Staff
Implementing a Struct of Arrays -- Barry Revzin https://isocpp.org//blog/2025/06/implementing-a-struct-of-arrays-barry-revzin https://isocpp.org//blog/2025/06/implementing-a-struct-of-arrays-barry-revzin Data-oriented design is all about reorganizing data for better performance, and Andrew Kelley’s talk on the topic—especially his use of Zig’s MultiArrayList—offered a compelling real-world example. Inspired by that, this post explores how we can achieve a similar “struct-of-arrays” approach in C++26 using reflection to build a SoaVector<T> that separates member storage for improved memory locality and performance.

Implementing a Struct of Arrays

by Barry Revzin

From the article:

Recently, I watched Andrew Kelley’s talk on Practical Data Oriented Design. It goes into some of the architectural changes he’s been making to the Zig compiler, with pretty significant performance benefit. Would definitely recommend checking out the talk, even if you’re like me and have never written any Zig.

About halfway through the talk, he shows a way to improve his memory usage by avoiding wasting memory. By turning this structure:

const Monster = struct { 
 anim : *Animation, 
 kind : Kind, 

 const Kind = enum { 
 snake, bat, wolf, dingo, human 
 }; 
}; 

var monsters : ArrayList(Monster) = .{}; 

into this one:

var monsters : MultiArrayList(Monster) = .{}; 

ArrayList(Monster) is what we could call std::vector<Monster>, and MultiArrayList(Monster) now stores the anims and kinds in two separate arrays, instead of one. That is, a struct of arrays instead of an array of structs. But it’s a tiny code change.

]]>
2025年6月23日 20:59:04 +0000 Blog Staff
Reflection voted into C++26: &quot;Whole new language&quot; -- Herb Sutter https://isocpp.org//blog/2025/06/reflection-voted-into-cpp26-whole-new-language-herb-sutter https://isocpp.org//blog/2025/06/reflection-voted-into-cpp26-whole-new-language-herb-sutter The first trip report from the Sofia meeting is available:

Trip report: June 2025 ISO C++ standards meeting (Sofia, Bulgaria)

by Herb Sutter

From the article:

c26-reflection.pngA unique milestone: “Whole new language”

Today marks a turning point in C++: A few minutes ago, the C++ committee voted the first seven (7) papers for compile-time reflection into draft C++26 to several sustained rounds of applause in the room. I think Hana “Ms. Constexpr” Dusíková summarized the impact of this feature best a few days ago, in her calm deadpan way… when she was told that the reflection paper was going to make it to the Saturday adoption poll, she gave a little shrug and just quietly said: “Whole new language.”

Mic drop.

]]>
2025年6月22日 05:16:16 +0000 Blog Staff
C++20 Concepts for Nicer Compiler Errors -- Daniel Lemire https://isocpp.org//blog/2025/06/cpp20-concepts-for-nicer-compiler-errors-daniel-lemire https://isocpp.org//blog/2025/06/cpp20-concepts-for-nicer-compiler-errors-daniel-lemire image-33-825x510.jpgTemplates are one of C++’s most powerful features, enabling developers to write generic, reusable code—but they come with a cost: notoriously verbose and opaque error messages. With the introduction of concepts in C++20, we can now impose clear constraints on template parameters and get far more helpful diagnostics when something goes wrong.

C++20 Concepts for Nicer Compiler Errors

by Daniel Lemire

From the article:

In C++, templates enable generic programming by allowing functions and classes to operate on different data types without sacrificing type safety. Defined using the template keyword, they let developers write reusable, type-agnostic code, such as functions (e.g., template <typename T> max(T a, T b)) or classes (e.g., std::vector), where the type T is specified at compile time.

Historically, the C++ language has tended to produce complicated compiler error messages. The main culprit is template metaprogramming. C++ templates are powerful but complex. When errors occur in template code, the compiler generates long, verbose messages with nested type information, often involving deep template instantiations. A simple mistake in a template function can produce a message spanning multiple lines with obscure type names.

Let us consider an example. In C++, we often use the ‘Standard Template Library (STL)’. It includes a useful dynamic array template: std::vector. A vector manages a sequence of elements with automatic memory handling and flexible sizing. Unlike fixed-size arrays, it can grow or shrink at runtime through operations like push_back to append elements or pop_back to remove them. You can store just about anything in an std::vector but there are some limits. For example, your type must be copyable.

]]>
2025年6月20日 00:14:43 +0000 Blog Staff
C++26: More constexpr in the Standard Library -- Sandor Dargo https://isocpp.org//blog/2025/06/cpp26-more-constexpr-in-the-standard-library-sandor-dargo https://isocpp.org//blog/2025/06/cpp26-more-constexpr-in-the-standard-library-sandor-dargo SANDOR_DARGO_ROUND.JPGHere are the standard library features that will soon be usable at compile time. One topic is missing: exceptions. As they need both core language and library changes, I thought they deserved their own post.

C++26: More constexpr in the Standard Library

by Sandor Dargo

From the article:

P2562R1: constexpr stable sorting

This paper proposes making std::stable_sort, std::stable_partition, std::inplace_merge, and their ranges counterparts usable in constant expressions. While many algorithms have become constexpr over the years, this family related to stable sorting had remained exceptions — until now.

The recent introduction of constexpr containers gives extra motivation for this proposal. If you can construct a container at compile time, it’s only natural to want to sort it there, too. More importantly, a constexpr std::vector can now support efficient, stable sorting algorithms.

A key question is whether the algorithm can meet its computational complexity requirements under the constraints of constant evaluation. Fortunately, std::is_constant_evaluated() provides an escape hatch for implementations. For deeper details, check out the proposal itself.

]]>
2025年6月14日 00:08:18 +0000 Blog Staff
Fixing exception safety in our task_sequencer -- Raymond Chen https://isocpp.org//blog/2025/06/fixing-exception-safety-in-our-task-sequencer-raymond-chen https://isocpp.org//blog/2025/06/fixing-exception-safety-in-our-task-sequencer-raymond-chen RaymondChen_5in-150x150.jpgSome time ago, we developed a task_sequencer class for running asynchronous operations in sequence. There’s a problem with the implementation of Queue­Task­Async: What happens if an exception occurs?

Fixing Exception Safety in our task_sequencer

by Raymond Chen

From the article:

Let’s look at the various places an exception can occur in Queue­Task­Async.

 template<typename Maker>
 auto QueueTaskAsync(Maker&& maker) ->decltype(maker())
 {
 auto current = std::make_shared<chained_task>();
 auto previous = [&]
 {
 winrt::slim_lock_guard guard(m_mutex);
 return std::exchange(m_latest, current); ← oops
 }();

 suspender suspend;

 using Async = decltype(maker());
 auto task = [](auto&& current, auto&& makerParam,
 auto&& contextParam, auto& suspend)
 -> Async
 {
 completer completer{ std::move(current) };
 auto maker = std::move(makerParam);
 auto context = std::move(contextParam);

 co_await suspend;
 co_await context;
 co_return co_await maker();
 }(current, std::forward<Maker>(maker),
 winrt::apartment_context(), suspend);

 previous->continue_with(suspend.handle);

 return task;
 }

If an exception occurs at make_shared, then no harm is done because we haven’t done anything yet.

If an exception occurs when starting the lambda task, then we are in trouble. We have already linked the current onto m_latest, but we will never call continue_with(), so the chain of tasks stops making progress.

To fix this, we need to delay hooking up the current to the chain of chained_tasks until we are sure that we have a task to chain.

]]>
2025年6月10日 00:08:25 +0000 Blog Staff
How to Join or Concat Ranges, C++26 -- Bartlomiej Filipek https://isocpp.org//blog/2025/06/how-to-join-or-concat-ranges-cpp26-bartlomiej-filipek https://isocpp.org//blog/2025/06/how-to-join-or-concat-ranges-cpp26-bartlomiej-filipek howtojoinconcat-filipek.pngC++ continues to refine its range library, offering developers more efficient and expressive ways to manipulate collections. In this post, we'll dive into three powerful range adaptors—concat_view, join_view, and join_with_view—exploring their differences, use cases, and practical examples.

How to Join or Concat Ranges, C++26

by Bartlomiej Filipek

From the article:

Modern C++ continuously improves its range library to provide more expressive, flexible, and efficient ways to manipulate collections. Traditionally, achieving tasks like concatenation and flattening required manual loops, copying, 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 differences, use cases, and examples.

std::ranges::concat_view (C++26)

The concat_view allows you to concatenate multiple independent ranges into a single sequence. Unlike join_view, it does not require a range of ranges—it simply merges the given ranges sequentially while preserving their structure.

In short:

  • Takes multiple independent ranges as arguments.
  • Supports random access if all underlying ranges support it.
  • Allows modification if underlying ranges are writable.
  • Lazy evaluation: No additional memory allocations.
]]>
2025年6月06日 00:02:04 +0000 Blog Staff
Function overloading is more flexible than template function specialization -- Raymond Chen https://isocpp.org//blog/2025/05/function-overloading-is-more-flexible-than-template-function-specialization https://isocpp.org//blog/2025/05/function-overloading-is-more-flexible-than-template-function-specialization RaymondChen_5in-150x150.jpgWhen trying to specialize a templated function for specific types, it’s easy to fall into subtle traps around how parameter types are matched. A colleague recently ran into this issue while attempting to specialize a function for a Widget and a string literal, only to be met with confusing compiler errors that hinted at deeper quirks in C++'s type deduction and function template specialization rules.

Function overloading is more flexible (and more convenient) than template function specialization

by Raymond Chen

From the article:

A colleague of mine was having trouble specializing a templated function. Here’s a simplified version.

template<typename T, typename U>
bool same_name(T const& t, U const& u)
{
 return t.name() == u.name();
}

They wanted to provide a specialization for the case that the parameters are a Widget and a string literal.

template<>
bool same_name<Widget, const char[]>(Widget const& widget, const char name[])
{
 return strcmp(widget.descriptor().name().c_str(), name) == 0;
}

However, this failed to compile:

// msvc
error C2912: explicit specialization 'bool 
same_name<Widget,const char[]>(const Widget &,const char 
[])' is not a specialization of a function template

What do you mean “not a specialization of a function template”? I mean doesn’t it look like a specialization of a function template? It sure follows the correct syntax for a function template specialization.

]]>
2025年5月30日 00:01:52 +0000 Blog Staff

AltStyle によって変換されたページ (->オリジナル) /