【问题标题】:FMT C++ library: allow user to set format specifiers for custom typeFMT C++ 库:允许用户为自定义类型设置格式说明符
【发布时间】: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

【问题讨论】:

    标签: c++ fmt


    【解决方案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 中构建格式字符串。只需重用您需要的格式化程序的专业化。
      猜你喜欢
      • 1970-01-01
      • 2022-01-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多