C++23 Formatting Ranges

C++23 added the ability to "print out" using formatting options a container directly instead of having to use some form of a loop to access each element individually. See:

https://github.com/Apress/beginning-cpp23/blob/main/Examples/Chapter%2005/Ex5_16.cpp

M'ok, the latest VS 2022 gets serious agita with this code, it only has partial support. :(

Luckily there is a workaround available:

https://github.com/Apress/beginning-cpp23/blob/main/Workarounds/format_ranges_workaround.h

#include that header after importing the stdlib and voila!

Default formatting: [1, 2, 3, 4]
No braces: 1, 2, 3, 4
Curly braces: {1, 2, 3, 4}
Format range only: [1, 2, 3, 4]
Format elements only: [1, 2, 3, 4]
All at once: 001, 010, 011, 100

This is so mondo neato cool!
Something that shows up in later examples with this workaround are problems when declaring the container to be const. const std::vector v{ 1, 2, 3, 4 };

{fmt}, the 3rd party library that was used to create the C++ stdlib formatting features has zero problem dealing with a const container. I stare at the workaround code and honestly I can't figure out why it doesn't like const. std::formatter code overall I find opaque....
Something that shows up in later examples with this workaround are problems when declaring the container to be const

Try adding const on line 48, changing from this:
auto format(T& range, std::format_context& ctx) const
To this:
auto format(T const& range, std::format_context& ctx) const
Last edited on
I knew it would likely be something really simple that I was missing. Thank you very much, mbozzi!

FYI, I actually changed line 48 to
auto format(const T& range, std::format_context& ctx) const

Now the workaround works the same as the {fmt} library, const container or not.

Ah, the curse and bane of being a self-taught C++ hobbyist. *Sigh* So much I know I don't know.

Oh, I earlier commented out the first two lines in the workaround when I was originally getting the const issues. Well, that didn't work to correct the const problem. Obviously.

1
2
// #include <version>
// import std; 

That way if you don't want to use the omnibus import std; it will work with importing individual C++ stdlib modules or including headers.

I think I will submit this const workaround change back to the authors' github.
Last edited on
Good to know and reminds me that I have more C++23 catching up to do.
I would recommend two books, one on C++20 and the other on C++23, by the same authors. The books have github repos, one I got the range formatting workaround from.

Beginning C++20: From Novice to Professional
https://link.springer.com/book/10.1007/978-1-4842-5884-2

Beginning C++23: From Beginner to Pro
https://link.springer.com/book/10.1007/978-1-4842-9343-0

Yes, they are eBooks, I have the C++20 book in a dead tree edition. And find it very flimsy and hard to read compared to the eBook.

I own both books and really recommend getting both. Each book cover much of the same material with examples and exercises of the other. The C++20 book has many of the examples/exercises that use modules in non-module form.

Visual Studio is still the only compiler that fully supports modules, even C++20 modules, though that is changing. No compiler is 100% compliant with C++23 yet.

I just recently did a re-read and code re-do of both books' code examples/exercises. Well worth the effort IMO 'cuz I learned some things I hadn't picked up on before.
Registered users can post here. Sign in or register to post.