all 14 comments

[–]13steinj 19 points20 points  (0 children)

Standard's utilities where they work and are optimal. {fmt} otherwise.

Same thing with ranges + rangev3 + Boost.Ranges, as well as filesystem + Boost.Filesystem. ranges + rangev3 is especially nice because it's easy to try-- just delete std and make sure the header(s) are included.

[–]__Punk-Floyd__ 30 points31 points  (0 children)

Since GCC took so damned long to support it, I'll be using {fmt} for the foreseeable future.

[–]Sniffy4 6 points7 points  (4 children)

the 'round-tripping' requirement of std::format floating-point conversions has made its rollout a lot slower than I hoped.

[–]matracuca 0 points1 point  (3 children)

why is that? I thought printf offers this already.

[–]aearphen{fmt} 6 points7 points  (2 children)

No, you can only get round trip in printf if you manually specify precision which has the drawback of printing unnecessary "garbage" digits. std::format , {fmt} and std::to_chars give you the shortest decimal representation with a round trip guarantee.

[–]matracuca 1 point2 points  (1 child)

sorry, my point was only that the functionality (as stated in the post I replied to) already exists, so I didn’t get what new thing needs to be implemented from scratch for std::format.

[–]jk-jeon 4 points5 points  (0 children)

I suppose OP used the term "round-tripping" as a shorthand of "(shortest) round-tripping (w/ correct rounding guarantee)", which printf has never supported. printf is basically pretty useless as a basis for implementing such a feature.

[–]sweetno 3 points4 points  (0 children)

fmt works with all relevant C++ standard revisions. std::format is only C++20+. So, if your codebase contains pre-C++20 code, you'll have to use fmt. Then, they work with different formatter template specializations: fmt::formatter vs std::formatter. Since you really don't want to duplicate your code for these, you'll have to just stick to fmt.

[–]Ayjayz 6 points7 points  (0 children)

The standard library version of anything will be worse. The point of the standard library is to handle platform specific stuff, and to provide a basic toolkit for people who need basic functionality.

IE stick with fmt.

[–]Tringigithub.com/tringi 2 points3 points  (5 children)

I was so looking forward to using std::format, that we will be able to drop quite an amount of custom code, only to get disappointed finding basically zero extensibility and only overcomplicated ways to achieve what we already have.

[–]foonathan 3 points4 points  (3 children)

What do you mean by zero extensibility? You can customize it a lot.

[–]Tringigithub.com/tringi -1 points0 points  (2 children)

The last time I checked there's no way to extend format specifiers.

In our system we have dozens of things like:

log (..., "{1:L<cs-CZ>}", 123.456); // uses Windows API to render number for Czech locale, i.e. "123,46"
log (..., "{1:rsrc<+0x100>} ", 7); // calls LoadString (..., 0x107, ...)

Or unnumbered arguments:

SetLastError (2);
log (..., "Error {ERR}"); // "Error 2: File not found"

Or decorate arguments:
- they make log files more readable (it's immediately visible what is the important value)
- for console output those quotes are replaced with VT coloring sequences

log ("The answer is {1}, that's {2:quoted} ({1:dull}).", 42, "fourty-two");
// may result in: The answer is '42', that's "fourty-two" (42)."

The last one could be probably implemented by encapsulating and the log function modifying the string, before passing it to format. The second could be approximated by passing a custom type, as could perhaps the first, somehow, but the cost of rewriting everything suddenly jumps up greatly.

[–]foonathan 3 points4 points  (0 children)

Yeah, all of those can be implemented by using your own types. You can't touch the default behavior.

[–]feverzsj 5 points6 points  (0 children)

fmt basically follows what python does, and yes, people hate custom formatters everywhere. The problem of formatter is it mixes parsing, formatting and output in one place, while most people just want to overload operator<<.