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

12

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

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

我该怎么做?

目前,当我设置自定义格式字符串时,我会得到:

 what():  unknown format specifier
2个回答

7
最简单的解决方案是让formatter<custom_type>继承formatter<double>:
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


1

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

    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;
    };

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接