C++20自定义std::formatter正确实现方式及三类实现要点验证
C++20自定义formatter的正确实现与问题验证
我查阅了多篇关于C++20格式化库自定义formatter的文章,但许多文章存在细微错误或无法在我的工具链上编译。以下是我认为正确的实现示例,并针对3个具体陈述判断其正确性:
#include <print> struct CustomType { int a; }; template<> struct std::formatter<CustomType> : std::formatter<int> { // 复用int的格式说明符解析逻辑 using std::formatter<int>::parse; auto format(CustomType const& x, auto & ctx) const { auto out = ctx.out(); out = std::format_to(out, "["); ctx.advance_to(out); out = std::formatter<int>::format(x.a, ctx); return std::format_to(out, "]"); } }; int main() { std::println("{:>2}", CustomType{1}); return 0; }
陈述正确性验证
1. format方法应针对格式上下文类型进行模板化,而非像许多在线示例那样使用std::format_context。
正确。标准要求formatter的format成员函数必须是模板函数,接受任意满足格式上下文要求的类型参数,而非固定使用std::format_context。因为格式化库需要支持不同的输出迭代器类型(比如普通指针、back_insert_iterator等),对应的上下文类型也会不同。固定使用std::format_context会限制formatter的通用性,甚至无法通过某些工具链的编译。
2. format方法应添加const限定符。
正确。formatter的format函数被调用时,实例是被当作const对象使用的(标准规定格式化过程中formatter对象不会被修改)。如果不添加const限定符,编译器会报错,因为无法将const的formatter对象绑定到非const成员函数上。
3. 使用format_to()时需要手动更新输出迭代器。多数示例省略了这一步,并假设使用的是std::back_insert_iterator,但据我所知,即使对于std::format_context,标准也未强制要求这一点。
正确。std::format_to会返回更新后的输出迭代器,指向写入后的下一个位置。标准并没有规定输出迭代器必须是back_insert_iterator这类会自动推进的类型,比如普通指针作为迭代器时,必须手动接收返回值来更新迭代器位置,否则后续写入会覆盖之前的内容。调用ctx.advance_to(out)也是为了让上下文知晓当前输出位置的变化,确保后续格式化操作能正确进行。
内容的提问来源于stack exchange,提问作者digitalvision
相关产品推荐
相关产品推荐

