std::formatter
来自cppreference.com
                    
                                        
                    
                    
                                                            
                    | 在标头  <format>定义 | ||
| template< class T, class CharT = char > struct formatter; | (C++20 起) | |
std::formatter 的被启用特化对给定类型定义格式化规则。被启用特化满足基本格式化器 (BasicFormatter) 要求,并且除非另有规定,否则也满足格式化器 (Formatter) 要求。
对每组未对其启用特化 std::formatter<T, CharT> 的类型 T 与 CharT,该特化是完整类型且被禁用。
被禁用特化不满足格式化器 (Formatter) 要求,且下列值都是 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
基本的标准特化
以下列表中,CharT 是 char 或 wchar_t,ArithmeticT 是除了 char、wchar_t、char8_t、char16_t 或 char32_t 之外的任何无 cv 限定的算术类型。
| 字符格式化器 | ||
| template<> struct formatter<char, char>; | (1) | |
| template<> struct formatter<char, wchar_t>; | (2) | |
| template<> struct formatter<wchar_t, wchar_t>; | (3) | |
| 字符串格式化器 | ||
| 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) | (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) | |
| 算术格式化器 | ||
| template<> struct formatter<ArithmeticT, CharT>; | (10) | |
| 指针格式化器 | ||
| template<> struct formatter<std::nullptr_t, CharT>; | (11) | |
| template<> struct formatter<void*, CharT>; | (12) | |
| template<> struct formatter<const void*, CharT>; | (13) | |
针对其他指针和成员指针的格式化器被禁用。
如 std::formatter<wchar_t, char> 和 std::formatter<const char*, wchar_t> 这些会要求编码转换的特化被禁用。
| C++23 中下列特化仍然被禁用,以避免将某些 char 序列作为 wchar_t 的范围格式化: 
 启用调试的格式化器特化都会另外提供一个公开的非静态成员函数 constexpr void set_debug_format();,它会修改格式化器对象的状态,使该对象可以在格式化时进行转义和使用引号包围,如同上次调用  每个针对字符串或字符类型的  | (C++23 起) | 
标准格式说明
| 本节未完成 原因:标准格式说明现已移动到单独页面。由于还有链接到此处,所以暂时保留此版块的标题。在解决那些链接后就会移除此版块。 | 
库类型的标准特化
| duration的格式化支持(类模板特化) | |
| sys_time的格式化支持(类模板特化) | |
| utc_time的格式化支持(类模板特化) | |
| tai_time的格式化支持(类模板特化) | |
| gps_time的格式化支持(类模板特化) | |
| file_time的格式化支持(类模板特化) | |
| local_time的格式化支持(类模板特化) | |
| day的格式化支持(类模板特化) | |
| month的格式化支持(类模板特化) | |
| year的格式化支持(类模板特化) | |
| weekday的格式化支持(类模板特化) | |
| weekday_indexed的格式化支持(类模板特化) | |
| weekday_last的格式化支持(类模板特化) | |
| month_day的格式化支持(类模板特化) | |
| month_day_last的格式化支持(类模板特化) | |
| month_weekday的格式化支持(类模板特化) | |
| month_weekday_last的格式化支持(类模板特化) | |
| year_month的格式化支持(类模板特化) | |
| year_month_day的格式化支持(类模板特化) | |
| year_month_day_last的格式化支持(类模板特化) | |
| year_month_weekday的格式化支持(类模板特化) | |
| year_month_weekday_last的格式化支持(类模板特化) | |
| hh_mm_ss的格式化支持(类模板特化) | |
| sys_info的格式化支持(类模板特化) | |
| local_info的格式化支持(类模板特化) | |
| zoned_time的格式化支持(类模板特化) | |
| basic_stacktrace的格式化支持(类模板特化) | |
| stacktrace_entry的格式化支持(类模板特化) | |
| thread::id的格式化支持(类模板特化) | |
| vector<bool>::reference的格式化支持(类模板特化) | |
| (C++23) | pair和tuple的格式化支持(类模板特化) | 
| (C++23) | 范围的格式化支持 (类模板特化) | 
| (C++23) | std::stack的格式化支持(类模板特化) | 
| (C++23) | std::queue的格式化支持(类模板特化) | 
| std::priority_queue的格式化支持(类模板特化) | |
| filesystem::path的格式化支持(类模板特化) | 
示例
运行此代码
#include <algorithm> #include <format> #include <iomanip> #include <iostream> #include <sstream> #include <string_view> struct QuotableString : std::string_view {}; template<> struct std::formatter<QuotableString, char> { bool quoted = false; template<class ParseContext> constexpr ParseContext::iterator parse(ParseContext& ctx) { auto it = ctx.begin(); if (it == ctx.end()) return it; if (*it == '#') { quoted = true; ++it; } if (it != ctx.end() && *it != '}') throw std::format_error("无效的 QuotableString 格式参数。"); return it; } template<class FmtContext> FmtContext::iterator format(QuotableString s, FmtContext& ctx) const { std::ostringstream out; if (quoted) out << std::quoted(s); else out << s; return std::ranges::copy(std::move(out).str(), ctx.out()).out; } }; int main() { QuotableString a("be"), a2(R"( " be " )"); QuotableString b("a question"); std::cout << std::format("To {0} or not to {0}, that is {1}.\n", a, b); std::cout << std::format("To {0:} or not to {0:}, that is {1:}.\n", a, b); std::cout << std::format("To {0:#} or not to {0:#}, that is {1:#}.\n", a2, b); }
输出:
To be or not to be, that is a question. To be or not to be, that is a question. To " \" be \" " or not to " \" be \" ", that is "a question".
缺陷报告
下列更改行为的缺陷报告追溯地应用于以前出版的 C++ 标准。
| 缺陷报告 | 应用于 | 出版时的行为 | 正确行为 | 
|---|---|---|---|
| LWG 3944 | C++23 | 某些 char 序列能作为 wchar_t 的范围格式化 | 添加了禁用的特化 | 
参阅
| (C++20)(C++20)(C++20) | 格式化状态,包括所有格式化参数和输出迭代器 (类模板) | 
| (C++23) | 指示一个类型可格式化,即它特化了 std::formatter 并且提供了成员函数 parse和format(概念) | 
| (C++23) | 用于帮助实现 std::formatter 对范围类型的特化的类模板 (类模板) |