fmt Knowledge Base
fmt is a fast, type-safe formatting library with Python-style replacement fields — {} holes in a
string, filled by arguments checked at compile time wherever possible. It is not just "a formatting
library": it is the reference implementation that P0645 turned into C++20's std::format, and it
still ships features the standard hasn't caught up with, from named arguments to color output to
support on toolchains that don't have std::format at all.
Roughly outside-in: Overview → Basics get you formatting strings today; the Format spec
mini-language is the reference you keep coming back to for every {:...} you write; Custom
types and Compile-time checks are what you need to use fmt across a real codebase instead of
just in a script; Advanced features and Performance are the allocation- and
throughput-sensitive corners you reach for once fmt is on a hot path.
Sections
| Section | What it covers | |
|---|---|---|
| Overview | What it is, installing it, its relationship to std::format, why not printf | |
| Basics | Replacement fields, the format/print/format_to family, named arguments | |
| Format Spec Mini-Language | The full spec grammar: fill, align, sign, width, precision, type, locale | |
| Formatting Custom Types | fmt::formatter<T>, the ostream bridge, ranges, std::chrono | |
| Compile-Time Checks | FMT_STRING, consteval checking, reading the errors | |
| Advanced Features | format_to, memory_buffer, color and styles, Unicode | |
| Performance & Best Practices | Where the speed comes from, build modes, migration, pitfalls |
Suggested reading paths
- Coming from printf: Comparison with printf → Format strings → Format spec syntax.
- Formatting your own types: formatter specialization → Ranges → Compile-time checks.
- Chasing allocations: format_to → memory_buffer → Performance characteristics.
Quick reference
#include <fmt/format.h>
#include <fmt/ranges.h>
std::string s = fmt::format("{} scored {:.1f}", name, score);
fmt::print("{:>10} | {:<10}\n", left, right); // aligned columns
fmt::print(stderr, "error: {}\n", msg);
fmt::memory_buffer buf; // no std::string allocation
fmt::format_to(std::back_inserter(buf), "{:08.3f}", x);
fmt::print("{}\n", std::vector{1, 2, 3}); // [1, 2, 3] via fmt/ranges.h
fmt::print("{}\n", fmt::join(v, ", ")); // 1, 2, 3
| Want | Spec |
|---|---|
| Right-align in 10 | {:>10} |
| Zero-pad to 8 | {:08} |
| 3 decimal places | {:.3f} |
Hex, with 0x | {:#x} |
| Binary | {:b} |
| Thousands separators | {:L} |
| Escape a brace | {{ |
| Named argument | fmt::format("{n}", fmt::arg("n", x)) |