命名空间
变体
操作

std::range_formatter

来自 cppreference.com
< cpp‎ | utility‎ | format
 
 
实用工具库
语言支持
类型支持 (基本类型、RTTI)
库功能测试宏 (C++20)
动态内存管理
程序实用工具
协程支持 (C++20)
可变参数函数
调试支持
(C++26)
三方比较
(C++20)
(C++20)(C++20)(C++20)
(C++20)(C++20)(C++20)
通用实用工具
日期和时间
函数对象
格式化库 (C++20)
(C++11)
关系运算符 (C++20 中已弃用)
整数比较函数
(C++20)(C++20)(C++20)   
(C++20)
交换类型操作
(C++14)
(C++11)
(C++11)
(C++11)
(C++17)
通用词汇类型
(C++11)
(C++17)
(C++17)
(C++17)
(C++11)
(C++17)
(C++23)
基本字符串转换
(C++17)
(C++17)

 
 
定义在头文件 <format>
template< class T, class CharT = char >

    requires std::same_as<std::remove_cvref_t<T>, T> && std::formattable<T, CharT>

class range_formatter;
(自 C++23 起)

std::range_formatter 是一个辅助类模板,用于实现 std::formatter 针对范围类型的特化。

内容

[编辑] 范围格式规范

range-format-spec 的语法为

range-fill-and-align (可选) width (可选) n(可选) range-type (可选) range-underlying-spec (可选)

range-fill-and-align 的解释方式与 fill-and-align 相同,只是 range-fill-and-align 中的 fill 为除 {}: 之外的任何字符。

width标准格式宽度规范 中描述。

n 选项会导致范围在没有开始和结束括号的情况下进行格式化。

assert(std::format("{}", views::iota(1, 5)) == "[1, 2, 3, 4]");
assert(std::format("{:n}", views::iota(1, 5)) == "1, 2, 3, 4");

range-underlying-spec 中的 format-spec (其语法等效于 : format-spec),如果存在,将由范围元素格式化程序 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_");

range-type 会改变范围的格式化方式,某些选项只对某些参数类型有效。

可用的范围表示类型为

  • m:表示开始括号应为 "{",结束括号应为 "}",分隔符应为 ", ",并且每个范围元素应像在 tuple-type 中指定了 m 一样进行格式化 (在 tuple-format-spec 中)。
  • 如果选择 m 作为 range-type,则除非 T 是以下类型的特化,否则程序将格式错误:
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 作为 range-type,则不应该在格式说明符中包含 n 选项和 range-underlying-spec,并且
  • 除非 TCharT,否则程序将格式错误。
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
为范围格式化结果设置指定的开括号和闭括号。
(公有成员函数)
底层
返回底层格式化器。
(公有成员函数)
解析
根据 范围格式规范 解析格式说明符。
(公有成员函数)
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;

分别将 openingclosing 赋值给 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> &&
           std::same_as<std::remove_cvref_t<ranges::range_reference_t<R>>, T>

auto format( R&& r, FormatContext& ctx ) const -> FormatContext::iterator;

如果 范围类型s?s,则将格式化的 std::basic_string<CharT>(std::from_range, r) 作为字符串或转义字符串分别写入 ctx.out() 中。

否则,根据 范围格式规范,按顺序将以下内容写入 ctx.out() 中:

  • opening-bracket_,
  • 对于范围 r 中的每个可格式化元素 e
  • 通过 underlying_ 写入 e 的结果,以及
  • separator_,除非 er 中的最后一个元素,以及
  • closing-bracket_.

返回指向输出范围末尾的迭代器。

[编辑] 缺陷报告

以下行为变更缺陷报告被追溯应用于之前发布的 C++ 标准。

DR 应用于 已发布的行为 正确行为
LWG 3892 C++23 嵌套范围的格式化不正确 已更正

[编辑] 另请参阅

(C++20)
为给定类型定义格式化规则
(类模板) [编辑]