std::formatter
Defined in header <format>
|
||
template<class T, class CharT = char> struct formatter; |
(since C++20) | |
The enabled specializations of formatter
define formatting rules for a given type. Enabled specializations meet the Formatter requirements. In particular, they define member functions or function templates parse
and format
, such that:
- The member
parse
...
- accepts a single parameter
pc
of type std::basic_format_parse_context<CharT> - parses the format specification for type
T
in the range[pc.begin(), pc.end())
- stores the parsed format specifiers in
*this
- returns a value of type std::basic_format_parse_context<CharT>::iterator that represents the end of format specification
- may throw std::format_error to indicate error in format string
- accepts a single parameter
- The member
format
...
- accepts two parameters: a parameter
t
of typeT
followed by a parameterfc
of type std::basic_format_context<OutputIt, CharT>, whereOutputIt
is an output iterator type - formats
t
according to the specifiers stored in*this
- writes the output to
fc.out()
- returns a value of type std::basic_format_context<OutputIt, CharT>::iterator that represents the end of output
- the output must only depend on
t
,fc.locale()
, and the last parsed format specifiers
- accepts two parameters: a parameter
Enabled specializations are DefaultConstructible, CopyConstructible, CopyAssignable, Swappable and Destructible.
For every types T
and CharT
for which neither the library nor the user provides an enabled specialization std::formatter<T, CharT>
, that specialization is a complete type and is disabled. Disabled specializations do not meet the Formatter requirements, and 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 are all false.
Standard specializations for basic types and string types
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
.
template<> struct formatter<char, char>; template<> struct formatter<char, wchar_t>; |
||
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.
Standard format specification
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.
fill and align
fill-and-align is an optional fill character (which can be any character other than {
or }
), followed by one of the align options <
, >
, ^
. The meaning of align options is as follows:
-
<
: Forces the field to be left-aligned within the available space. This is the default when a non-integer non-floating-point presentation type is used. -
>
: Forces the field to be right-aligned within the available space. This is the default when an integer or floating-point presentation type is used. -
^
: Forces the field to be centered within the available space by inserting ⌊
⌋ characters before and ⌈n 2
⌉ characters after the value, where n is the total number of fill characters to insert.n 2
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 "
sign, #, and 0
The sign option can be one of following:
-
+
: Indicates that a sign should be used for both non-negative and negative numbers. -
-
: Indicates that a sign should be used only for negative numbers (this is the default behavior). - space: Indicates that a leading space should be used for non-negative numbers, and a minus sign for negative numbers.
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.
- For integral types, when binary, octal, or hexadecimal presentation type is used, the alternate form adds the prefix (
0b
,0
, or0x
) to the output value. - For floating-point types, the alternate form causes the result of the conversion to always contain a decimal-point character, even if no digits follow it. Normally, a decimal-point character appears in the result of these conversions only if a digit follows it. In addition, for
g
andG
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 and precision
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. For floating-point types, this field specifies the formatting precision. For string types, it specifies how many characters will be used from the string.
This section is incomplete Reason: mini-example |
L (locale-specific formatting)
The L
option causes the locale-specific form to be used. This option is only valid for arithmetic types.
- For integral types, the locale-specific form inserts the appropriate digit group separator characters according to the context's locale.
- For floating-point types, the locale-specific form inserts the appropriate digit group and radix separator characters according to the context's locale.
- For the textual representation of
bool
, the locale-specific form uses the appropriate string as if obtained with std::numpunct::truename or std::numpunct::falsename.
type
The type option determines how the data should be presented.
The available string presentation types are:
- none,
s
: Copies the string to the output.
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 is0b
. -
B
: same asb
, except that the base prefix is0B
. -
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 is0
if the corresponding argument value is nonzero and is empty otherwise. -
x
: Hex format. Produces the output as if by calling std::to_chars(first, last, value, 16). The base prefix is0x
. -
X
: same asx
, except that it uses uppercase letters for digits above 9 and the base prefix is0X
. - none: same as
d
.
The available char
and wchar_t
presentation types are:
- none,
c
: Copies the character to the output. -
b
,B
,d
,o
,x
,X
: Uses integer presentation types.
The available bool
presentation types are:
- none,
s
: Copies textual representation (true
orfalse
, or the locale-specific form) to the output. -
b
,B
,c
,d
,o
,x
,X
: Uses integer presentation types with the valuestatic_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) whereprecision
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 asa
, except that it uses uppercase letters for digits above 9 and usesP
to indicate the exponent. -
e
: Produces the output as if by calling std::to_chars(first, last, value, std::chars_format::scientific, precision) whereprecision
is the specified precision, or 6 if precision is not specified. -
E
: same ase
, except that it uses usesE
to indicate the exponent. -
f
,F
: Produces the output as if by calling std::to_chars(first, last, value, std::chars_format::fixed, precision) whereprecision
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) whereprecision
is the specified precision, or 6 if precision is not specified. -
G
: same asg
, except that it uses usesE
to indicate the exponent. - none: If precision is specified, produces the output as if by calling 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:
- none,
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 prefix0x
added to the output; otherwise, the output is implementation-defined.
Standard specializations for library types
specialization of std::formatter that formats a duration according to the provided format (class template specialization) | |
specialization of std::formatter that formats a sys_time according to the provided format (class template specialization) | |
specialization of std::formatter that formats a utc_time according to the provided format (class template specialization) | |
specialization of std::formatter that formats a tai_time according to the provided format (class template specialization) | |
specialization of std::formatter that formats a gps_time according to the provided format (class template specialization) | |
specialization of std::formatter that formats a file_time according to the provided format (class template specialization) | |
specialization of std::formatter that formats a local_time according to the provided format (class template specialization) | |
specialization of std::formatter that formats a day according to the provided format (class template specialization) | |
specialization of std::formatter that formats a month according to the provided format (class template specialization) | |
specialization of std::formatter that formats a year according to the provided format (class template specialization) | |
specialization of std::formatter that formats a weekday according to the provided format (class template specialization) | |
specialization of std::formatter that formats a weekday_indexed according to the provided format (class template specialization) | |
specialization of std::formatter that formats a weekday_last according to the provided format (class template specialization) | |
specialization of std::formatter that formats a month_day according to the provided format (class template specialization) | |
specialization of std::formatter that formats a month_day_last according to the provided format (class template specialization) | |
specialization of std::formatter that formats a month_weekday according to the provided format (class template specialization) | |
specialization of std::formatter that formats a month_weekday_last according to the provided format (class template specialization) | |
specialization of std::formatter that formats a year_month according to the provided format (class template specialization) | |
specialization of std::formatter that formats a year_month_day according to the provided format (class template specialization) | |
specialization of std::formatter that formats a year_month_day_last according to the provided format (class template specialization) | |
specialization of std::formatter that formats a year_month_weekday according to the provided format (class template specialization) | |
specialization of std::formatter that formats a year_month_weekday_last according to the provided format (class template specialization) | |
specialization of std::formatter that formats a hh_mm_ss according to the provided format (class template specialization) | |
specialization of std::formatter that formats a sys_info according to the provided format (class template specialization) | |
specialization of std::formatter that formats a local_info according to the provided format (class template specialization) | |
specialization of std::formatter that formats a zoned_time according to the provided format (class template specialization) |
Example
#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) { return std::formatter<T, CharT>::format(t.value, fc); } }; int main() { Box<int> v = { 42 }; std::cout << std::format("{:#x}", v); }
Output:
0x2a