使用 fmt 库格式化用户定义类型的问题

Posted

技术标签:

【中文标题】使用 fmt 库格式化用户定义类型的问题【英文标题】:Problem with Formatting User-defined Types with fmt library 【发布时间】:2019-07-24 23:02:09 【问题描述】:

我遇到了格式化用户定义类型的问题,最终得到了这个基于 fmt 文档的简单示例。

struct point_double 
    double x, y;

    operator const char*() const 
        return nullptr;
    
;

namespace fmt 
template <>
struct formatter<point_double> 
    template <typename ParseContext>
    constexpr auto parse(ParseContext& ctx) 
        return ctx.begin();
    

    template <typename FormatContext>
    auto format(const point_double& p, FormatContext& ctx) 
        return format_to(ctx.out(), "(:.1f, :.1f)", p.x, p.y);
    
;
  // namespace fmt

void foo() 
    point_double p = 1, 2;
    fmt::print("\n", p);

调用foo 会崩溃,因为没有使用用户定义的格式化程序。相反,fmt::print 将使用默认的字符串格式化程序并在运算符返回 nullptr 时崩溃。 有没有办法解决这个问题?我正在使用 fmt 5.3.0

【问题讨论】:

【参考方案1】:

你不能同时隐式转换为const char*formatter 特化(fmt 现在会给你一个编译时错误),因为const char* 已经是可格式化的。如果您可以控制point_double,一个简单的解决方案是明确转换运算符,这通常是一个好主意。否则,您可以将 point_double 包装在另一种类型中,并为此提供 formatter 特化。

【讨论】:

以上是关于使用 fmt 库格式化用户定义类型的问题的主要内容,如果未能解决你的问题,请参考以下文章

js时间类型的自定义转换库 datetime-fmt

将任意文本添加到 fmt 的用户定义类型格式化程序

添加自定义类型格式,以及所有常用选项

fmtlib:没有解析选项的用户定义类型的快捷方式?

带有外部模板的自定义类型 fmt 格式化程序,有啥缺点吗?

Go 语言fmt 标准库格式化输出说明