std::formatter
| ヘッダ <format> で定義
|
||
template<class T, class CharT = char> struct formatter; |
(C++20以上) | |
formatter の有効化された特殊化は特定の型の書式化ルールを定義します。 有効化された特殊化は Formatter の要件を満たします。 特に、以下のようなメンバ関数または関数テンプレート parse および format を定義します。
- メンバ
parseは...
- 1個の引数、
std::basic_format_parse_context<CharT>型の引数pcを取ります。 - 範囲
[pc.begin(), pc.end())のT型のための書式指定を解析します。 - 解析した書式指定子を
*thisに格納します。 - 書式指定の終端を表す
std::basic_format_parse_context<CharT>::iterator型の値を返します。 - 書式文字列内のエラーを表すために std::format_error を投げても構いません。
- 1個の引数、
- メンバ
formatは...
- 2個の引数、
T型の引数tおよびstd::basic_format_context<OutputIt, CharT>型の引数fcを受理します。 ただしOutputItは出力イテレータの型です。 *thisに格納された書式指定子に従ってtを書式化します。- 出力を
fc.out()に書き出します。 - 出力の終端を表す
std::basic_format_context<OutputIt, CharT>::iterator型の値を返します。 - 出力は
t、fc.locale()、および最後に解析された書式指定子にのみ依存しなければなりません。
- 2個の引数、
有効化された特殊化は DefaultConstructible、 CopyConstructible、 CopyAssignable、 Swappable、 Destructible です。
ライブラリもユーザも std::formatter<T, CharT> の有効化された特殊化を提供しないすべての T および CharT 型について、その特殊化は完全型ですが、無効化されます。 無効化された特殊化は Formatter の要件を満たさず、 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 はすべて false です。
基本型および文字列型に対する標準の特殊化
以下の一覧において、 CharT は char または wchar_t のいずれか、 ArithmeticT は char、 wchar_t、 char8_t、 char16_t、 char32_t 以外の任意の cv 修飾されていない算術型です。
template<> struct formatter<char, char>; template<> struct formatter<char, wchar_t>; template<> struct formatter<wchar_t, wchar_t>; template<> struct formatter<CharT*, CharT>; template<> struct formatter<const CharT*, CharT>; template<std::size_t N> struct formatter<const CharT[N], CharT>; template<class Traits, class Alloc> struct formatter<std::basic_string<CharT, Traits, Alloc>, CharT>; template<class Traits> struct formatter<std::basic_string_view<CharT, Traits>, CharT>; template<> struct formatter<ArithmeticT, CharT>; template<> struct formatter<std::nullptr_t, CharT>; template<> struct formatter<void*, CharT>; template<> struct formatter<const void*, CharT>; |
||
それ以外のポインタおよびメンバポインタに対するフォーマッタは無効化されています。
エンコーディング変換を必要とする std::formatter<wchar_t, char> や std::formatter<const char*, wchar_t> のような特殊化は無効化されています。
標準の書式指定
基本型および文字列型に対する書式指定は Python の書式指定がベースになっています。
書式指定の構文は以下の通りです。
fill-and-align(オプション) sign(オプション) #(オプション) 0(オプション) width(オプション) precision(オプション) L(オプション) type(オプション)
|
|||||||||
オプション sign、 # および 0 は整数または浮動小数点の表示形式が使用されたときのみ有効です。
フィルとアライン
fill-and-align はオプショナルなフィル文字 ({ および } 以外の任意の文字が使用できます) と、それに続くアラインオプション (<、 >、 ^ のいずれか) です。 アラインオプションの意味は以下の通りです。
<: フィールドを利用可能な空間内で強制的に左詰めにします。 これは整数でも浮動小数点でも表示形式が使用されたときのデフォルトです。>: フィールドを利用可能な空間内で強制的に右詰めにします。 これは整数または浮動小数点の表示形式が使用されたときのデフォルトです。^: フィールドを利用可能な空間内で強制的に中央寄せにします。 値の前に ⌊
⌋ 個の文字を、値の後に ⌈n 2
⌉ 個の文字を挿入します。 ただし n は挿入するフィル文字の合計個数です。n 2
char c = 120;
auto s0 = std::format("{:6}", 42); // s0 の値は " 42" です。
auto s1 = std::format("{:6}", 'x'); // s1 の値は "x " です。
auto s2 = std::format("{:*<6}", 'x'); // s2 の値は "x*****" です。
auto s3 = std::format("{:*>6}", 'x'); // s3 の値は "*****x" です。
auto s4 = std::format("{:*^6}", 'x'); // s4 の値は "**x***" です。
auto s5 = std::format("{:6d}", c); // s5 の値は " 120" です。
auto s6 = std::format("{:6}", true); // s6 の値は "true " です。
符号、#、および0
sign オプションは以下のいずれかです。
+: 非負の数値と負の数値の両方に対して符号を使用するべきであることを示します。-: 負の数値に対してのみ符号を使用するべきであることを示します (デフォルトの動作)。- スペース: 非負の数値に対しては空白、負の数値に対しては負号を使用するべきであることを示します。
sign オプションは浮動小数点の無限大および 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); // s0 の値は "1,+1,1, 1" です。
auto s1 = std::format("{0:},{0:+},{0:-},{0: }", -1); // s1 の値は "-1,-1,-1,-1" です。
auto s2 = std::format("{0:},{0:+},{0:-},{0: }", inf); // s2 の値は "inf,+inf,inf, inf" です。
auto s3 = std::format("{0:},{0:+},{0:-},{0: }", nan); // s3 の値は "nan,+nan,nan, nan" です。
# オプションは代替形式を変換に使用させます。
- 整数型の場合、2進数、8進数、または16進数の表示形式が使用されたときは、代替形式では出力値に接頭辞 (
0b、0、または0x) が追加されます。 - 浮動小数点型の場合、代替形式では変換の結果に必ず小数点文字が含まれます (たとえ小数点以下が1桁も無くても)。 通常は、小数点文字は、その後に数字が1桁以上続く場合にのみ、変換結果に現れます。 さらに、
gおよびG変換の場合は、結果から末尾のゼロが削除されません。
0 オプションは前にゼロを付けてフィールド幅を埋めます (符号や基数はゼロの前に付きます) (無限大や NaN のときは除く)。 文字 0 とアラインオプションが両方現れた場合は、文字 0 は無視されます。
char c = 120;
auto s1 = std::format("{:+06d}", c); // s1 の値は "+00120" です。
auto s2 = std::format("{:#06x}", 0xa); // s2 の値は "0x000a" です。
auto s3 = std::format("{:<06}", -42); // s3 の値は "-42 " です (アライン < により 0 は無視されます)
幅と精度
width は正の10進数またはネストした置換フィールド ({} または {n}) のいずれかです。 これは、存在する場合は、最小フィールド幅を指定します。
precision はドット (.) の後に非負の10進数またはネストした置換フィールドが続いたものです。 これは精度または最大フィールド幅を指定します。 浮動小数点および文字列型に対してのみ使用できます。 浮動小数点型の場合は書式化の精度を指定します。 文字列型の場合は文字列から何個の文字を使用するかを指定します。
| This section is incomplete Reason: mini-example |
L (ロケール固有の書式化)
L オプションはロケール固有の形式を使用させます。 このオプションは算術型に対してのみ有効です。
- 整数型の場合、ロケール固有の形式では文脈のロケールに従った適切な桁区切り文字を挿入します。
- 浮動小数点型の場合、ロケール固有の形式では文脈のロケールに従った適切な桁区切り文字および小数点文字を挿入します。
boolのテキスト表現の場合、ロケール固有の形式では std::numpunct::truename または std::numpunct::falsename を用いて取得したかのような適切な文字列を使用します。
型
type オプションはデータをどのように表示するべきかを決定します。
利用可能な文字列の表示形式は以下の通りです。
- (なし)、
s: 文字列を出力にコピーします。
char、 wchar_t、 bool 以外の整数型に対する利用可能な整数の表示形式は以下の通りです。
b: 2進数形式。std::to_chars(first, last, value, 2)を呼んだかのような出力が生成されます。 基数接頭辞は0bです。B:bと同じですが、基数接頭辞は0Bです。c: 文字static_cast<CharT>(value)を出力にコピーします。 ただしCharTは書式文字列の文字型です。 値がCharTで表現可能な値の範囲内でない場合は std::format_error を投げます。d: 10進数形式。std::to_chars(first, last, value)を呼んだかのように出力が生成されます。o: 8進数形式。std::to_chars(first, last, value, 8)を呼んだかのように出力が生成されます。 基数接頭辞は値が非ゼロの場合は0、そうでなければ空です。x: 16進数形式。std::to_chars(first, last, value, 16)を呼んだかのように出力が生成されます。 基数接頭辞は0xです。X:xと同じですが、9より大きな数字は大文字を使用し、基数接頭辞は0Xです。- (なし):
dと同じです。
利用可能な char および wchar_t の表示形式は以下の通りです。
- (なし)、
c: 文字を出力にコピーします。 b、B、d、o、x、X: 整数の表示形式を使用します。
利用可能な bool の表示形式は以下の通りです。
- (なし)、
s: テキスト表現 (trueまたはfalse、またはロケール固有の形式) を出力にコピーします。 b、B、c、d、o、x、X: 値static_cast<unsigned char>(value)を使用して整数の表示形式を使用します。
利用可能な浮動小数点の表示形式は以下の通りです。
a: 精度が指定されている場合は、 std::to_chars(first, last, value, std::chars_format::hex, precision) を呼んだかのように出力が生成されます。 ただしprecisionは指定された精度です。 そうでなければ、 std::to_chars(first, last, value, std::chars_format::hex) を呼んだかのように出力が生成されます。A:aと同じですが、9より大きな数字は大文字を使用し、指数を示すためにPを使用します。e: std::to_chars(first, last, value, std::chars_format::scientific, precision) を呼んだかのように出力を生成します。 ただしprecisionは指定された精度、または指定されていない場合は 6 です。E:eと同じですが、指数を示すためにEを使用します。f,F: std::to_chars(first, last, value, std::chars_format::fixed, precision) を呼んだかのように出力を生成します。 ただしprecisionは指定された精度、または指定されていない場合は 6 です。g: std::to_chars(first, last, value, std::chars_format::general, precision) を呼んだかのように出力を生成します。 ただしprecisionは指定された精度、または指定されていない場合は 6 です。G:gと同じですが、指数を示すためにEを使用します。- (なし): 精度が指定された場合は、 std::to_chars(first, last, value, std::chars_format::general, precision) を呼んだかのように出力を生成します。 ただし
precisionは指定された精度です。 そうでなければ、 std::to_chars(first, last, value) を呼んだかのように出力が生成されます。
小文字の表示形式の場合、無限大および NaN はそれぞれ inf および nan のように書式化されます。
大文字の表示形式の場合、無限大および NaN はそれぞれ INF および NAN のように書式化されます。
利用可能なポインタの表示形式は以下の通りです (std::nullptr_t の場合も使用されます)。
- (なし)、
p: std::uintptr_t が定義されている場合は、std::to_chars(first, last, reinterpret_cast<std::uintptr_t>(value), 16)を呼んだかのように出力が生成され、接頭辞0xがその出力に追加されます。 そうでなければ、出力は処理系定義です。
ライブラリ型に対する標準の特殊化
提供された書式に従って duration を書式化する std::formatter の特殊化 (クラステンプレートの特殊化) | |
提供された書式に従って sys_time を書式化する std::formatter の特殊化 (クラステンプレートの特殊化) | |
提供された書式に従って utc_time を書式化する std::formatter の特殊化 (クラステンプレートの特殊化) | |
提供された書式に従って tai_time を書式化する std::formatter の特殊化 (クラステンプレートの特殊化) | |
提供された書式に従って gps_time を書式化する std::formatter の特殊化 (クラステンプレートの特殊化) | |
提供された書式に従って file_time を書式化する std::formatter の特殊化 (クラステンプレートの特殊化) | |
提供された書式に従って local_time を書式化する std::formatter の特殊化 (クラステンプレートの特殊化) | |
提供された書式に従って day を書式化する std::formatter の特殊化 (クラステンプレートの特殊化) | |
提供された書式に従って month を書式化する std::formatter の特殊化 (クラステンプレートの特殊化) | |
提供された書式に従って year を書式化する std::formatter の特殊化 (クラステンプレートの特殊化) | |
提供された書式に従って weekday を書式化する std::formatter の特殊化 (クラステンプレートの特殊化) | |
提供された書式に従って weekday_indexed を書式化する std::formatter の特殊化 (クラステンプレートの特殊化) | |
提供された書式に従って weekday_last を書式化する std::formatter の特殊化 (クラステンプレートの特殊化) | |
提供された書式に従って month_day を書式化する std::formatter の特殊化 (クラステンプレートの特殊化) | |
提供された書式に従って month_day_last を書式化する std::formatter の特殊化 (クラステンプレートの特殊化) | |
提供された書式に従って month_weekday を書式化する std::formatter の特殊化 (クラステンプレートの特殊化) | |
提供された書式に従って month_weekday_last を書式化する std::formatter の特殊化 (クラステンプレートの特殊化) | |
提供された書式に従って year_month を書式化する std::formatter の特殊化 (クラステンプレートの特殊化) | |
提供された書式に従って year_month_day を書式化する std::formatter の特殊化 (クラステンプレートの特殊化) | |
提供された書式に従って year_month_day_last を書式化する std::formatter の特殊化 (クラステンプレートの特殊化) | |
提供された書式に従って year_month_weekday を書式化する std::formatter の特殊化 (クラステンプレートの特殊化) | |
提供された書式に従って year_month_weekday_last を書式化する std::formatter の特殊化 (クラステンプレートの特殊化) | |
提供された書式に従って hh_mm_ss を書式化する std::formatter の特殊化 (クラステンプレートの特殊化) | |
提供された書式に従って sys_info を書式化する std::formatter の特殊化 (クラステンプレートの特殊化) | |
提供された書式に従って local_info を書式化する std::formatter の特殊化 (クラステンプレートの特殊化) | |
提供された書式に従って zoned_time を書式化する std::formatter の特殊化 (クラステンプレートの特殊化) |
例
#include <format>
#include <iostream>
// T 型のためのラッパー。
template<class T>
struct Box {
T value;
};
// ラッパー Box<T> はラップされている値の書式指定を使用して書式化できます。
template<class T, class CharT>
struct std::formatter<Box<T>, CharT> : std::formatter<T, CharT> {
// parse() は基底クラスから継承されます。
// format() を定義します。 ラップされている値を使用して基底クラスの実装を呼びます。
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);
}
出力:
0x2a