Mert Köklü
Mert Köklü

Reputation: 2231

How can I use C++20 std::format?

C++20 introduces std::format. What are the advantages over printf or std::cout? How can I use it and someone give an example of it?

Upvotes: 32

Views: 30424

Answers (2)

paxdiablo
paxdiablo

Reputation: 881093

C++20's std::format is primarily just the inclusion of the fmt library that many people are already using (we use it as part of the spdlog logging framework).

So, if you want to use it, you can just download fmt.

As for advantages over streams, it has the type-safety but without the verbosity. Legacy-C printf is concise but neither type-safe nor extensible, so std::format has both those advantages.

Here's an example (slightly modified) from my own code base:

std::string idStr = fmt::format("prefix.{:05d}.suffix", id);

This would have otherwise required the rather less than concise standard C++:

std::string idStr;
{
    std::stringstream ss;
    ss << "prefix." << std::setfill('0') << std::setw(5) << id << ".suffix";
    idStr = ss.str();
}

As an aside, I would have liked to have seen C++ go one step further and provide something akin to Python's f-string functionality, rather than its current str.format() capability. This would have involved embedding the arguments inline in the actual string. In other words, turning this:

std::string idStr = fmt::format("prefix.{:05d}.suffix{:d}", id, num);

into something like this:

std::string idStr = fmt::format("prefix.{id:05d}.suffix{num:d}");

Making the arguments inline would make reading the code much nicer since you don't have to look ahead to figure out which argument is used to format each specifier.

Upvotes: 25

eerorika
eerorika

Reputation: 238281

What are the advantages over printf

Type safety. For printf, the programmer must carefully match the format specifier to the type of the argument. If they make a mistake, the behaviour of the program is undefined. This is a very common source of bugs, especially for beginners.

To be fair, decent compilers diagnose these mistakes as long as a constant format string is used, as long as the programmer has remembered / knows how to enable the warnings. Regardless, it is much more convenient, and safer to use template argument deduction to choose the formatted type automatically.

Furthermore, there is no way to extend printf to support printing class types.

or std::cout

Stream manipulators are quite cumbersome and verbose, and have inconsistent behaviour. Some manipulators are "sticky", affecting all subsequent insertions, while others only affect only a single insertion.

The lack of separation between the format and the arguments in the iostream API arguably makes it harder to comprehend the (intended) result.

How can I use it

Either wait for your compiler / standard library implementation to support it. Or if don't want to wait, use the original non-standard version instead. Then follow the documentation.

The normative specification is the C++ standard. There are also websites that present the standard, including this library in a more convenient format. Another good source of information is the standard proposal. The repo for the non-standard version (linked in previous paragraph) also has tons of documentation, although there will be differences to what will be in the standard.

and someone give an example of it?

Here you go (adapted from the documentation of libfmt):

std::string s = std::format("I'd rather be {1} than {0}.", "right", "happy");

Upvotes: 32

Related Questions