Sometimes, we want more than to just iterate over all the elements of a range. We also want the index of each element. If we had something like a vector<T>, then a simple for loop suffices 1: for (int i = 0; i < vec.size(); ++i) { // use i or vec[i] } But for a range that can’t be...
Copy-on-write with Deducing this
One of the new language features for C++23 is Deducing this, which is a feature I co-authored with Gašper Ažman, Sy Brand, and Ben Deane. The interesting history there is that Sy and I were working on solving one problem (deduplication of all the const and ref-qualifier overloads) and Gašper and ...
Assignment for optional<T>
Let’s talk about assignment for optional<T>. I realize this is a fraught topic, but I want to try to build up proper intuition about how assignment has to work, especially since the debate around this topic has been fairly underwhelming. This post will almost exclusively discuss copy assign...
Projections are Function Adaptors
There was a question recently on StackOverflow where a user was confused about the purpose of projections in a way that I think is fairly common. They wanted to do something like this: struct Person { std::string first; std::string last; }; std::vector<Person> people = { /* ... */...
Improving Output Iterators
Let’s say we had a range, represented by a pair of pointers, that we wanted to copy into another pointer. We might write that like so: template <typename T, typename U> void copy(T* first, T* last, U* out) { for (; first != last; ++first) { *out++ = *first; } } For trivia...
For Hannah
We drove Hannah home for the first time on November 10, 2012. We drove her home for the final time on December 29, 2021. In between, we got nine years of memories, milestones, and love. When we first met Hannah, she was probably around six years old, we really don’t know. She was a puppy mill ...
T*
makes for a poor optional<T&>
Whenever the idea of an optional reference comes up, inevitably somebody will bring up the point that we don’t need to support optional<T&> because we already have in the language a perfectly good optional reference: T*. And these two types are superficially quite similar, which makes ...
Conditional Members
I’d previously written a post about if constexpr (and how it’s not broken). I argued in that post how, broadly speaking, C++20 gives you the tools to solve the problems you want, even if they work a bit differently to D’s static if (with one notable exception, which this post greatly expands on)....
Coercing deep const-ness
In C++, template deduction doesn’t allow for any conversion. A type matches the pattern, or it’s a deduction failure. But there’s one sort-of exception to this rule, and it’s an exception that everyone has taken advantage of: template <typename T> void takes_ptr(T const*); void f(int i) {...
Counting in Iteration Models
There’s a really interesting issue pointed out in the July 2021 mailing by way of P2406R0. Basically, in C++, the iterator loop structure ordering is as follows (I wrote it with a goto to make the ordering more obvious. Note that in C++, we start with the it != end check, not the ++it operation....