23

In a related question ("std::string formatting like sprintf") I learned about this awesome new C++20 header <format>.

However, there seems to be no supporting compiler. Is this correct or is there a way to use it anyway?
I'm using g++ 9.3 with the -std=c++2a flag and the library <format> is not recognised.

#include <format> // fatal error: format: No such file or directory
#include <iostream>

int main(){
    std::cout << std::format("Hello {}!", "World");
}

g++-9 test.cpp -o test -std=c++2a

Deduplicator
  • 44,692
  • 7
  • 66
  • 118
infinitezero
  • 1,610
  • 3
  • 14
  • 29

3 Answers3

17

Use libfmt. The <format> header is essentially a standardized libfmt (with a few small features removed, if I remember correctly).

HolyBlackCat
  • 78,603
  • 9
  • 131
  • 207
  • 1
    "*The header is heavily inspired by it.*" No, that's project is [touted as](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p0645r10.html) a"full *implementation*" of the library. – Nicol Bolas Apr 26 '20 at 13:34
  • @NicolBolas I could be wrong, but doesn't libfmt predate the `` proposal? – HolyBlackCat Apr 26 '20 at 13:38
  • It may have predated the proposal, but it seems to have tracked the proposal's development. Since, you know, the proposal and library are written by the same person;) – Nicol Bolas Apr 26 '20 at 13:40
  • @NicolBolas Oh. I'll change the wording. – HolyBlackCat Apr 26 '20 at 13:44
  • Thanks, I made it work with the following steps: 1. Clone repo, make build subdir, `cmake ..` (with options you want) and `make` as usual. 2. Either `make install` to your system, or add include path, lib path and lib linking to your C++ project config. 3. Replace `#include "` with `#include ` (or `"fmt/format.h"` if you don't consider it system header). 4. Replace all `std::(format function)` with `fmt::(format function)`. If you want agnostic code that won't change when is added to std, you'll need a proxy... – hsandt Jul 13 '20 at 12:09
4

There is a libfmt-dev package available on debian/ubuntu.
I currently use this header as a replacement for the format header:

#include <fmt/core.h>
#include <fmt/ranges.h>

namespace std
{
   template<typename... Args>
   inline auto format(Args&&... args) -> decltype(fmt::v7::format(std::forward<Args>(args)...))
   {
      return fmt::v7::format(std::forward<Args>(args)...);
   }
}

This is experimental: I don't know exactly what are the differences between std::format and fmt::format.
Life is full of surprises

Kiruahxh
  • 1,276
  • 13
  • 30
  • Thanks for the answer, but this library is already mentioned in the other answer – infinitezero Apr 07 '21 at 19:19
  • With this header, the fmtlib is a a droppin replacement for std::format: you can switch between std::format and fmt::format without modifying your code. – Kiruahxh Apr 08 '21 at 07:11
4

As of the time of writing, MSVC and Clang are the only 2 compilers supporting the header.

fjch1997
  • 1,518
  • 18
  • 19