20 General utilities library [utilities]

20.20 Formatting [format]

20.20.5 Formatter [format.formatter] Formatter specializations [format.formatter.spec]

The functions defined in [format.functions] use specializations of the class template formatter to format individual arguments.
Let charT be either char or wchar_­t.
Each specialization of formatter is either enabled or disabled, as described below.
Enabled specializations meet the Formatter requirements, and disabled specializations do not.
— end note
Each header that declares the template formatter provides the following enabled specializations:
  • The specializations
    template<> struct formatter<char, char>;
    template<> struct formatter<char, wchar_t>;
    template<> struct formatter<wchar_t, wchar_t>;
  • For each charT, the string type specializations
    template<> struct formatter<charT*, charT>;
    template<> struct formatter<const charT*, charT>;
    template<size_t N> struct formatter<const charT[N], charT>;
    template<class traits, class Allocator>
      struct formatter<basic_string<charT, traits, Allocator>, charT>;
    template<class traits>
      struct formatter<basic_string_view<charT, traits>, charT>;
  • For each charT, for each cv-unqualified arithmetic type ArithmeticT other than char, wchar_­t, char8_­t, char16_­t, or char32_­t, a specialization
    template<> struct formatter<ArithmeticT, charT>;
  • For each charT, the pointer type specializations
    template<> struct formatter<nullptr_t, charT>;
    template<> struct formatter<void*, charT>;
    template<> struct formatter<const void*, charT>;
The parse member functions of these formatters interpret the format specification as a std-format-spec as described in [format.string.std].
Specializations such as formatter<wchar_­t, char> and formatter<const char*, wchar_­t> that would require implicit multibyte / wide string or character conversion are disabled.
— end note
For any types T and charT for which neither the library nor the user provides an explicit or partial specialization of the class template formatter, formatter<T, charT> is disabled.
If the library provides an explicit or partial specialization of formatter<T, charT>, that specialization is enabled except as noted otherwise.
If F is a disabled specialization of formatter, these values are false:
  • is_­default_­constructible_­v<F>,
  • is_­copy_­constructible_­v<F>,
  • is_­move_­constructible_­v<F>,
  • is_­copy_­assignable_­v<F>, and
  • is_­move_­assignable_­v<F>.
An enabled specialization formatter<T, charT> meets the Formatter requirements ([formatter.requirements]).
#include <format>

enum color { red, green, blue };
const char* color_names[] = { "red", "green", "blue" };

template<> struct std::formatter<color> : std::formatter<const char*> {
  auto format(color c, format_context& ctx) {
    return formatter<const char*>::format(color_names[c], ctx);

struct err {};

std::string s0 = std::format("{}", 42);         // OK, library-provided formatter
std::string s1 = std::format("{}", L"foo");     // error: disabled formatter
std::string s2 = std::format("{}", red);        // OK, user-provided formatter
std::string s3 = std::format("{}", err{});      // error: disabled formatter
— end example