std::range_formatter
在标头 <format> 定义
|
||
template< class T, class CharT = char > requires std::same_as<std::remove_cvref_t<T>, T> && std::formattable<T, CharT> |
(C++23 起) | |
std::range_formatter
是用于实现 std::formatter 针对范围类型的特化的辅助类模板。
范围格式说明
范围格式说明 的语法是:
范围填充与对齐 (可选) 宽度 (可选) n (可选) 范围类型 (可选) 范围底层说明 (可选)
|
|||||||||
范围填充与对齐 与 填充与对齐 的判读方式相同,但 范围填充与对齐 中的 填充 是除 {
、}
和 :
外的任意字符。
宽度 在标准格式宽度说明中描述。
n
选项导致格式化范围时没有开闭括号。
assert(std::format("{}", views::iota(1, 5)) == "[1, 2, 3, 4]"); assert(std::format("{:n}", views::iota(1, 5)) == "1, 2, 3, 4");
范围底层说明(其语法等价于 :
格式说明)中的 格式说明,如果有,由范围元素格式化器 std::formatter<T, CharT>
判读。
std::array ints{12, 10, 15, 14}; assert(std::format("{}", ints) == "[12, 10, 15, 14]"); assert(std::format("{::X}", ints) == "[C, A, F, E]"); assert(std::format("{:n:_^4}", ints) == "_12_, _10_, _15_, _14_");
范围类型 改变格式化范围的方式,某些选项仅对特定实参类型有效。
可用的范围表示类型有:
-
m
:指示开括号应为 "{",闭括号应为 "}",分隔符应为 ", ",且每个范围元素应当如同以m
作为(元组格式说明 中的)元组类型 来格式化。
- 如果选择
m
为 范围类型,则除非T
是以下各项的特化,否则程序非良构:
- std::pair,或者
- std::tuple 且满足 std::tuple_size_v<T> == 2 为 true。
- 如果选择
std::array char_pairs { std::pair{'A', 5}, std::pair{'B', 10}, std::pair{'C', 12} }; assert(std::format("{}", char_pairs) == "[('A', 5), ('B', 10), ('C', 12)]"); assert(std::format("{:m}", char_pairs) == "{'A': 5, 'B': 10, 'C': 12}");
-
s
:指示范围应当被格式化为字符串。 -
?s
:指示范围应当被格式化为有转义字符串。
- 如果选择
s
或?s
为 范围类型,则n
选项和 范围底层说明 都不能出现于格式说明符中,并且 - 除非
T
为CharT
否则程序非良构。
- 如果选择
std::array star{'S', 'T', 'A', 'R'}; assert(std::format("{}", star) == "['S', 'T', 'A', 'R']"); assert(std::format("{:s}", star) == "STAR"); assert(std::format("{:?s}", star) == "\"STAR\"");
成员对象
成员名字 | 定义 |
underlying_ (私有)
|
std::formatter<T, CharT> 类型的底层格式化器 (仅用于阐述的成员对象*) |
separator_ (私有)
|
表示范围格式化结果的分隔符的字符串。默认分隔符为 ", "。 (仅用于阐述的成员对象*) |
opening-bracket_ (私有)
|
表示范围格式化结果的开括号的字符串。默认开括号为 "["。 (仅用于阐述的成员对象*) |
closing-bracket_ (私有)
|
表示范围格式化结果的闭括号的字符串。默认闭括号为 "]"。 (仅用于阐述的成员对象*) |
成员函数
set_separator |
设置范围格式化结果所用的分隔符 (公开成员函数) |
set_brackets |
设置范围格式化结果所用的开括号和闭括号 (公开成员函数) |
underlying |
返回底层格式化器 (公开成员函数) |
parse |
按 范围格式说明 的说明解析格式说明符 (公开成员函数) |
format |
按 范围格式说明 写入范围的已格式化输出 (公开成员函数) |
std::range_formatter::set_separator
constexpr void set_separator( std::basic_string_view<CharT> sep ) noexcept; |
||
赋值 sep 为 separator_
。
std::range_formatter::set_brackets
constexpr void set_brackets( std::basic_string_view<CharT> opening, std::basic_string_view<CharT> closing ) noexcept; |
||
分别赋值 opening 和 closing 为 opening-bracket_
和 closing-bracket_
。
std::range_formatter::underlying
constexpr std::formatter<T, CharT>& underlying(); |
(1) | |
constexpr const std::formatter<T, CharT>& underlying() const; |
(2) | |
返回 underlying_
(底层格式化器)。
std::range_formatter::parse
template< class ParseContext > constexpr auto parse( ParseContext& ctx ) -> ParseContext::iterator; |
||
将各个格式说明符解析为 范围格式说明 并将解析的说明符存储到当前对象中。
调用 underlying_
.parse(ctx) 来解析 范围格式说明 中的 格式说明,或者若没有前者则使用空 格式说明。
如果有 范围类型 或 n
选项,那么按需要修改 opening-bracket_
、closing-bracket_
和 separator_
的值。
它在以下情况下调用 underlying_
.set_debug_format():
- 范围类型 不是
s
也不是?s
, -
underlying_
.set_debug_format() 是有效表达式,且 - 没有 范围底层说明。
返回 范围格式说明 的尾后迭代器。
std::range_formatter::format
template< ranges::input_range R, class FormatContext > requires std::formattable<ranges::range_reference_t<R>, CharT> && |
||
如果 范围类型 为 s
或 ?s
,那么它将已格式化的 std::basic_string<CharT>(std::from_range, r) 分别作为字符串和有转义字符串写入 ctx.out()。
否则,它根据 范围格式说明 将以下内容依序写入 ctx.out():
-
opening-bracket_
, - 对范围 r 中的每个可格式化元素 e:
- 通过
underlying_
写入 e 的结果,和 -
separator_
,除非 e 是 r 的最末元素,以及
- 通过
-
closing-bracket_
。
返回输出范围的尾后迭代器。
缺陷报告
下列更改行为的缺陷报告追溯地应用于以前出版的 C++ 标准。
缺陷报告 | 应用于 | 出版时的行为 | 正确行为 |
---|---|---|---|
LWG 3892 | C++23 | 嵌套范围的格式化不正确 | 已修正 |
参阅
(C++20) |
定义针对给定类型的格式化规则 (类模板) |