FMT C++ 库:允许用户为自定义类型设置格式说明符

Posted

技术标签:

【中文标题】FMT C++ 库:允许用户为自定义类型设置格式说明符【英文标题】:FMT C++ library: allow user to set format specifiers for custom type 【发布时间】:2019-05-20 11:40:00 【问题描述】:

我有一个自定义类型,例如

struct custom_type

    double value;
;

我想为此类型设置自定义 FMT 格式化程序。我做了以下,它的工作原理:

namespace fmt

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

    template <typename FormatContext>
    auto format(const custom_type &v, FormatContext &ctx) 
        return format_to(ctx.begin(), "", v.value);
    
;

但问题是,输出格式是由模板代码设置的,带有 "" 表达式。我想给一个用户自己定义格式字符串的机会。

例如:

custom_type v = 10.0;
std::cout << fmt::format("", v) << std::endl;    // 10
std::cout << fmt::format(":+f", v) << std::endl; // 10.000000

我该怎么做?

目前,当我设置自定义格式字符串时,我得到 ​​p>

 what():  unknown format specifier

【问题讨论】:

【参考方案1】:

最简单的解决方案是从formatter&lt;double&gt;继承formatter&lt;custom_type&gt;

template <> struct fmt::formatter<custom_type> : formatter<double> 
  auto format(custom_type c, format_context& ctx) 
    return formatter<double>::format(c.value, ctx);
  
;

https://godbolt.org/z/6AHCOJ

【讨论】:

【参考方案2】:

我终于做到了。我会把它保存在这里,以防其他人需要它。

    template <>
    struct formatter<custom_type> 
        template <typename ParseContext>
        constexpr auto parse(ParseContext &ctx) 
            auto it = internal::null_terminating_iterator<char>(ctx);
            std::string tmp;
            while(*it && *it != '') 
            
                tmp += *it;
                ++it;
            
            m_format=tmp;
            return internal::pointer_from(it);
        

        template <typename FormatContext>
        auto format(const custom_type &v, FormatContext &ctx) 
            std::string final_string;
            if(m_format.size()>0)
               
                final_string=":"+m_format+"";
            
            else
            
                final_string="";
            
            return format_to(ctx.begin(), final_string, v.value);
        
        mutable std::string m_format;
    ;

【讨论】:

您实际上不需要使用任何内部 API 或在 format 中构建格式字符串。只需重用您需要的格式化程序的专业化。

以上是关于FMT C++ 库:允许用户为自定义类型设置格式说明符的主要内容,如果未能解决你的问题,请参考以下文章

spdlog 基本结构分析

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

C++ fmt 库,仅使用格式说明符格式化单个参数

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

带有 fmt 的自定义格式说明符用于自定义类

c++为自定义矩阵类实现迭代器