【问题标题】:Custom format specifier with {fmt} for custom class带有 {fmt} 的自定义格式说明符用于自定义类
【发布时间】:2019-10-04 03:42:35
【问题描述】:

在格式化我自己的自定义类型时,我将如何允许自定义填充等?

struct S
{
   int x;
};

template<> struct fmt::formatter<S> {
    template <typename ParseContext>
        constexpr auto parse(ParseContext& ctx) { return ctx.begin(); }

    template <typename FormatContext>
        auto format(const S& s, FormatContext& ctx)
        {
            return format_to(ctx.out(), "{}", s.x);
        }
};

S s; s.x = 1;
fmt::format("{:<10}", s); // error

【问题讨论】:

    标签: c++ fmt


    【解决方案1】:

    由于您似乎只重用现有的格式说明符,您可以将操作转发到formatter&lt;int&gt;

    template<> struct fmt::formatter<S> {
        formatter<int> int_formatter;
    
        template <typename ParseContext>
            constexpr auto parse(ParseContext& ctx)
            {
                return int_formatter.parse(ctx);
            }
    
        template <typename FormatContext>
            auto format(const S& s, FormatContext& ctx)
            {
                return int_formatter.format(s.x, ctx);
            }
    };
    

    如果你想使用不同的语法,或者你不想依赖formatter&lt;int&gt;,你也可以手动解析formatter::parse中的格式字符串。

    template<> struct fmt::formatter<S> {
        enum { left, right } align = right;
        int width = 0;
    
        template <typename ParseContext>
            constexpr auto parse(ParseContext& ctx)
            {
                auto it = ctx.begin();
    
                // parse /align/
                if (*it == '<') {
                    align = left;
                    ++it;
                }
    
                // parse /width/
                const char* width_str_begin = std::to_address(it);
                const char* width_str_bound = std::to_address(ctx.end());
                auto [ptr, ec] = std::from_chars(width_str_begin, width_str_bound, width);
                auto length = ptr - width_str_begin;
                it += length;
    
                // error handling omitted
    
                return it;
            }
    
        template <typename FormatContext>
            auto format(const S& s, FormatContext& ctx)
            {
                return format_to(ctx.out(), align == left ? "{:<{}}" : "{:>{}}", s.x, width);
            }
    };
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-04
      • 1970-01-01
      • 2019-12-10
      • 1970-01-01
      相关资源
      最近更新 更多