A std::format primer

As mentioned in a previous post, the popular C++ {fmt} library has been added to Modern C++ (in the form of the standard header <format>). This library’s development into standardization has seen a number of considerable improvements over the original, which of course remains available to non-bleeding-edge versions of compilers. The latest Microsoft C++ compiler (version 19.29 at the time of writing) supports std::format and supporting functions (by using either #include <format> or import std.core; with /std:c++latest in the options). This compiler was used to test the example code below, also requiring using namespace std;.

The return value of a call to std::format can be assigned to a std::string variable. Much like C’s printf(), a format string (actually a std::string_view) appears first, followed by zero or more values to be formatted into the output. Unlike printf() though, no format-type specifier is needed and the output is virtually guaranteed to be type-safe; the sequence to insert a parameter is {} rather than %a:

string message = format("Hello, {}!", "world");
cout << message << endl;

Alternatively, an iterator (usually of type char) can be supplied avoiding the need for an intermediate variable:

format_to(ostream_iterator<char>(cout), "The result of {} divided by {} is {}.\n", 3, 4, 3./4);

One of the key design features is the ability to explicitly declare positional values, which allows for internationalization of software where the order of substituted fields may need to be different, without need to alter the source code:

cout << format("I'd rather be {1} than {0}!\n", "happy", "rich");

Field format modifiers are also supported, this is to print to accuracy of 10 figures:

cout << format("10 divided by 3 is {0:.{1}}\n", 10./3, 10);

To wrap up this primer, note that it is possible to use named (rather than numbered) positional parameters, and include them more than once:

cout << format("Hello, {name}! The answer is {number}. Goodbye, {name}.", "name"_a="World", "number"_a=42);

(Sadly, this functionality had not made it into Microsoft’s implementation at the time of writing.)

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s