Defined in header <format> | ||
|---|---|---|
template< class T, class CharT = char > struct formatter; | (since C++20) |
The enabled specializations of std::formatter define formatting rules for a given type. Enabled specializations meet the BasicFormatter requirements, and, unless otherwise specified, also meet the Formatter requirements.
For all types T and CharT for which no specialization std::formatter<T, CharT> is enabled, that specialization is a complete type and is disabled.
Disabled specializations do not meet the Formatter requirements, and the following are all false:
std::is_default_constructible_v std::is_copy_constructible_v std::is_move_constructible_v std::is_copy_assignable_v std::is_move_assignable_v. In the following list, CharT is either char or wchar_t, ArithmeticT is any cv-unqualified arithmetic type other than char, wchar_t, char8_t, char16_t, or char32_t:
| Character formatters | ||
template<> struct formatter<char, char>; | (1) | |
template<> struct formatter<char, wchar_t>; | (2) | |
template<> struct formatter<wchar_t, wchar_t>; | (3) | |
| String formatters | ||
template<> struct formatter<CharT*, CharT>; | (4) | |
template<> struct formatter<const CharT*, CharT>; | (5) | |
template< std::size_t N > struct formatter<CharT[N], CharT>; | (6) | |
template< std::size_t N > struct formatter<const CharT[N], CharT>; | (7) | (until C++23) |
template< class Traits, class Alloc > struct formatter<std::basic_string<CharT, Traits, Alloc>, CharT>; | (8) | |
template< class Traits > struct formatter<std::basic_string_view<CharT, Traits>, CharT>; | (9) | |
| Arithmetic formatters | ||
template<> struct formatter<ArithmeticT, CharT>; | (10) | |
| Pointer formatters | ||
template<> struct formatter<std::nullptr_t, CharT>; | (11) | |
template<> struct formatter<void*, CharT>; | (12) | |
template<> struct formatter<const void*, CharT>; | (13) |
Formatters for other pointers and pointers to members are disabled.
Specializations such as std::formatter<wchar_t, char> and std::formatter<const char*, wchar_t> that would require encoding conversions are disabled.
| Each formatter specialization for string or character type additionally provides a public non-static member function | (since C++23) |
For basic types and string types, the format specification is based on the format specification in Python.
The syntax of format specifications is:
fill-and-align (optional) sign (optional) #(optional) 0(optional) width (optional) precision (optional) L(optional) type (optional) |
The sign, # and 0 options are only valid when an integer or floating-point presentation type is used.
In most of the cases the syntax is similar to the old %-formatting, with the addition of the {} and with : used instead of %. For example, '%03.2f' can be translated to '{:03.2f}'.
fill-and-align is an optional fill character (which can be any character other than { or }), followed by one of the align options <, >, ^.
If no fill character is specified, it defaults to the space character. For a format specification in a Unicode encoding, the fill character must correspond to a single Unicode scalar value.
The meaning of align options is as follows:
<: Forces the formatted argument to be aligned to the start of the available space by inserting n fill characters after the formatted argument. This is the default when a non-integer non-floating-point presentation type is used. >: Forces the formatted argument to be aligned to the end of the available space by inserting n fill characters before the formatted argument. This is the default when an integer or floating-point presentation type is used. ^: Forces the formatted argument to be centered within the available space by inserting ⌊n/2⌋ characters before and ⌈n/2⌉ characters after the formatted argument. In each case, n is the difference of the minimum field width and the estimated width of the formatted argument, or 0 if the difference is less than 0.
char c = 120;
auto s0 = std::format("{:6}", 42); // value of s0 is " 42"
auto s1 = std::format("{:6}", 'x'); // value of s1 is "x "
auto s2 = std::format("{:*<6}", 'x'); // value of s2 is "x*****"
auto s3 = std::format("{:*>6}", 'x'); // value of s3 is "*****x"
auto s4 = std::format("{:*^6}", 'x'); // value of s4 is "**x***"
auto s5 = std::format("{:6d}", c); // value of s5 is " 120"
auto s6 = std::format("{:6}", true); // value of s6 is "true "The sign option can be one of following:
+: Indicates that a sign should be used for both non-negative and negative numbers. The + sign is inserted before the output value for non-negative numbers. -: Indicates that a sign should be used for negative numbers only (this is the default behavior). Negative zero is treated as a negative number.
The sign option applies to floating-point infinity and NaN.
double inf = std::numeric_limits<double>::infinity();
double nan = std::numeric_limits<double>::quiet_NaN();
auto s0 = std::format("{0:},{0:+},{0:-},{0: }", 1); // value of s0 is "1,+1,1, 1"
auto s1 = std::format("{0:},{0:+},{0:-},{0: }", -1); // value of s1 is "-1,-1,-1,-1"
auto s2 = std::format("{0:},{0:+},{0:-},{0: }", inf); // value of s2 is "inf,+inf,inf, inf"
auto s3 = std::format("{0:},{0:+},{0:-},{0: }", nan); // value of s3 is "nan,+nan,nan, nan"The # option causes the alternate form to be used for the conversion.
0b, 0, or 0x) into the output value after the sign character (possibly space) if there is one, or add it before the output value otherwise. g and G conversions, trailing zeros are not removed from the result. The 0 option pads the field with leading zeros (following any indication of sign or base) to the field width, except when applied to an infinity or NaN. If the 0 character and an align option both appear, the 0 character is ignored.
char c = 120;
auto s1 = std::format("{:+06d}", c); // value of s1 is "+00120"
auto s2 = std::format("{:#06x}", 0xa); // value of s2 is "0x000a"
auto s3 = std::format("{:<06}", -42); // value of s3 is "-42 "
// (0 is ignored because of < alignment)width is either a positive decimal number, or a nested replacement field ({} or {n}). If present, it specifies the minimum field width.
precision is a dot (.) followed by either a non-negative decimal number or a nested replacement field. This field indicates the precision or maximum field size. It can only be used with floating-point and string types.
If a nested replacement field is used for width or precision, and the corresponding argument is not of integral type (until C++23)standard signed or unsigned integer type (since C++23), or is negative, an exception of type std::format_error is thrown.
float pi = 3.14f;
auto s1 = std::format("{:10f}", pi); // s1 = " 3.140000" (width = 10)
auto s2 = std::format("{:{}f}", pi, 10); // s2 = " 3.140000" (width = 10)
auto s3 = std::format("{:.5f}", pi); // s3 = "3.14000" (precision = 5)
auto s4 = std::format("{:.{}f}", pi, 5); // s4 = "3.14000" (precision = 5)
auto s5 = std::format("{:10.5f}", pi); // s5 = " 3.14000"
// (width = 10, precision = 5)
auto s6 = std::format("{:{}.{}f}", pi, 10, 5); // s6 = " 3.14000"
// (width = 10, precision = 5)
auto b1 = std::format("{:{}f}", pi, 10.0); // throws: width is not of integral type
auto b2 = std::format("{:{}f}", pi, -10); // throws: width is negative
auto b3 = std::format("{:.{}f}", pi, 5.0); // throws: precision is not of integral typeFor string types, the width is defined as the estimated number of column positions appropriate for displaying it in a terminal.
For the purpose of width computation, a string is assumed to be in an implementation-defined encoding. The method of width computation is unspecified, but for a string in a Unicode encoding, implementation should estimate the width of the string as the sum of estimated widths of the first code points in its extended grapheme clusters. The estimated width is 2 for the following code points, and is 1 otherwise:
East_Asian_Width has value Fullwidth (F) or Wide (W) auto s1 = std::format("{:.^5s}", "🐱"); // s1 = ".🐱.."
auto s2 = std::format("{:.5s}", "🐱🐱🐱"); // s2 = "🐱🐱"
auto s3 = std::format("{:.<5.5s}", "🐱🐱🐱"); // s3 = "🐱🐱."The L option causes the locale-specific form to be used. This option is only valid for arithmetic types.
bool, the locale-specific form uses the appropriate string as if obtained with std::numpunct::truename or std::numpunct::falsename. The type option determines how the data should be presented.
The available string presentation types are:
s: Copies the string to the output.
| (since C++23) |
The available integer presentation types for integral types other than char, wchar_t, and bool are:
b: Binary format. Produces the output as if by calling std::to_chars(first, last, value, 2). The base prefix is 0b. B: same as b, except that the base prefix is 0B. c: Copies the character static_cast<CharT>(value) to the output, where CharT is the character type of the format string. Throws std::format_error if value is not in the range of representable values for CharT. d: Decimal format. Produces the output as if by calling std::to_chars(first, last, value). o: Octal format. Produces the output as if by calling std::to_chars(first, last, value, 8). The base prefix is 0 if the corresponding argument value is non-zero and is empty otherwise. x: Hex format. Produces the output as if by calling std::to_chars(first, last, value, 16). The base prefix is 0x. X: same as x, except that it uses uppercase letters for digits above 9 and the base prefix is 0X. d. The available char and wchar_t presentation types are:
c: Copies the character to the output. b, B, d, o, x, X: Uses integer presentation types.
| (since C++23) |
The available bool presentation types are:
s: Copies textual representation (true or false, or the locale-specific form) to the output. b, B, d, o, x, X: Uses integer presentation types with the value static_cast<unsigned char>(value). The available floating-point presentation types are:
a: If precision is specified, produces the output as if by calling std::to_chars(first, last, value, std::chars_format::hex, precision) where precision is the specified precision; otherwise, the output is produced as if by calling std::to_chars(first, last, value, std::chars_format::hex). A: same as a, except that it uses uppercase letters for digits above 9 and uses P to indicate the exponent. e: Produces the output as if by calling std::to_chars(first, last, value, std::chars_format::scientific, precision) where precision is the specified precision, or 6 if precision is not specified. E: same as e, except that it uses E to indicate the exponent. f, F: Produces the output as if by calling std::to_chars(first, last, value, std::chars_format::fixed, precision) where precision is the specified precision, or 6 if precision is not specified. g: Produces the output as if by calling std::to_chars(first, last, value, std::chars_format::general, precision) where precision is the specified precision, or 6 if precision is not specified. G: same as g, except that it uses E to indicate the exponent. std::to_chars(first, last, value, std::chars_format::general, precision) where precision is the specified precision; otherwise, the output is produced as if by calling std::to_chars(first, last, value). For lower-case presentation types, infinity and NaN are formatted as inf and nan, respectively. For upper-case presentation types, infinity and NaN are formatted as INF and NAN, respectively.
The available pointer presentation types (also used for std::nullptr_t) are:
p: If std::uintptr_t is defined, produces the output as if by calling std::to_chars(first, last, reinterpret_cast<std::uintptr_t>(value), 16) with the prefix 0x added to the output; otherwise, the output is implementation-defined. A character or string can be formatted as escaped to make it more suitable for debugging or for logging.
Escaping is done as follows:
| Character | Escape sequence | Notes |
|---|---|---|
| horizontal tab (byte 0x09 in ASCII encoding) | \t | |
| line feed - new line (byte 0x0a in ASCII encoding) | \n | |
| carriage return (byte 0x0d in ASCII encoding) | \r | |
| double quote (byte 0x22 in ASCII encoding) | \" | Used only if the output is a double-quoted string |
| single quote (byte 0x27 in ASCII encoding) | \' | Used only if the output is a single-quoted string |
| backslash (byte 0x5c in ASCII encoding) | \\ |
General_Category has a value in the groups Separator (Z) or Other (C), or Grapheme_Extend=Yes, or \u{hex-digit-sequence}, where hex-digit-sequence is the shortest hexadecimal representation of C using lower-case hexadecimal digits. \x{hex-digit-sequence}, where hex-digit-sequence is the shortest hexadecimal representation of the code unit using lower-case hexadecimal digits. The escaped string representation of a string is constructed by escaping the code unit sequences in the string, as described above, and quoting the result with double quotes.
The escaped representation of a character is constructed by escaping it as described above, and quoting the result with single quotes.
auto s1 = std::format("[{:?}]", "h\tllo"); // s1 has value: ["h\tllo"]
auto s2 = std::format("[{:?}]", "Спасибо, Виктор ♥!"); // s2 has value:
// ["Спасибо, Виктор ♥!"]
auto s3 = std::format("[{:?}] [{:?}]", '\'', '"'); // s3 has value: ['\'', '"']
// The following examples assume use of the UTF-8 encoding
auto s4 = std::format("[{:?}]", std::string("\0 \n \t \x02 \x1b", 9));
// s4 has value:
// [\u{0} \n \t \u{2} \u{1b}]
auto s5 = std::format("[{:?}]", "\xc3\x28"); // invalid UTF-8
// s5 has value: ["\x{c3}("]
auto s6 = std::format("[{:?}]", "\u0301"); // s6 has value: ["\u{301}"]
auto s7 = std::format("[{:?}]", "\\\u0301"); // s7 has value: ["\\\u{301}"]
auto s8 = std::format("[{:?}]", "e\u0301\u0323"); // s8 has value: ["ẹ́"]|
(C++20) | formatting support for duration (class template specialization) |
|
(C++20) | formatting support for sys_time (class template specialization) |
|
(C++20) | formatting support for utc_time (class template specialization) |
|
(C++20) | formatting support for tai_time (class template specialization) |
|
(C++20) | formatting support for gps_time (class template specialization) |
|
(C++20) | formatting support for file_time (class template specialization) |
|
(C++20) | formatting support for local_time (class template specialization) |
|
(C++20) | formatting support for day (class template specialization) |
|
(C++20) | formatting support for month (class template specialization) |
|
(C++20) | formatting support for year (class template specialization) |
|
(C++20) | formatting support for weekday (class template specialization) |
|
(C++20) | formatting support for weekday_indexed (class template specialization) |
|
(C++20) | formatting support for weekday_last (class template specialization) |
|
(C++20) | formatting support for month_day (class template specialization) |
|
(C++20) | formatting support for month_day_last (class template specialization) |
|
(C++20) | formatting support for month_weekday (class template specialization) |
|
(C++20) | formatting support for month_weekday_last (class template specialization) |
|
(C++20) | formatting support for year_month (class template specialization) |
|
(C++20) | formatting support for year_month_day (class template specialization) |
|
(C++20) | formatting support for year_month_day_last (class template specialization) |
|
(C++20) | formatting support for year_month_weekday (class template specialization) |
|
(C++20) | formatting support for year_month_weekday_last (class template specialization) |
|
(C++20) | formatting support for hh_mm_ss (class template specialization) |
|
(C++20) | formatting support for sys_info (class template specialization) |
|
(C++20) | formatting support for local_info (class template specialization) |
|
(C++20) | formatting support for zoned_time (class template specialization) |
|
(C++23) | formatting support for basic_stacktrace (class template specialization) |
|
(C++23) | formatting support for stacktrace_entry (class template specialization) |
|
(C++23) | formatting support for thread::id (class template specialization) |
#include <format>
#include <iostream>
// A wrapper for type T
template<class T>
struct Box
{
T value;
};
// The wrapper Box<T> can be formatted using the format specification of the wrapped value
template<class T, class CharT>
struct std::formatter<Box<T>, CharT> : std::formatter<T, CharT>
{
// parse() is inherited from the base class
// Define format() by calling the base class implementation with the wrapped value
template<class FormatContext>
auto format(Box<T> t, FormatContext& fc) const
{
return std::formatter<T, CharT>::format(t.value, fc);
}
};
int main()
{
Box<int> v = {42};
std::cout << std::format("{:#x}", v);
}Output:
0x2a
The following behavior-changing defect reports were applied retroactively to previously published C++ standards.
| DR | Applied to | Behavior as published | Correct behavior |
|---|---|---|---|
| LWG 3721 | C++20 | zero is not allowed for the width field in standard format specification | zero is permitted if specified via a replacement field |
|
(C++20)(C++20)(C++20) | formatting state, including all formatting arguments and the output iterator (class template) |
© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/w/cpp/utility/format/formatter