fmtlib 格式化 基本用法 2——扩展类型

12 篇文章 0 订阅

fmtlib 库扩展自定义类型,需要 特化模板类:struct fmt::formatter

实现自定义的 point 扩展

#include <iostream>
#include <fmt/format.h>
using namespace std;


struct point {
    double x, y;
};

template <> struct fmt::formatter<point> {
    // Presentation format: 'f' - fixed, 'e' - exponential.
    char presentation = 'f';

    // Parses format specifications of the form ['f' | 'e'].
    constexpr auto parse(format_parse_context& ctx) -> format_parse_context::iterator {
        // [ctx.begin(), ctx.end()) is a character range that contains a part of
        // the format string starting from the format specifications to be parsed,
        // e.g. in
        //
        //   fmt::format("{:f} - point of interest", point{1, 2});
        //
        // the range will contain "f} - point of interest". The formatter should
        // parse specifiers until '}' or the end of the range. In this example
        // the formatter should parse the 'f' specifier and return an iterator
        // pointing to '}'.

        // Please also note that this character range may be empty, in case of
        // the "{}" format string, so therefore you should check ctx.begin()
        // for equality with ctx.end().

        // Parse the presentation format and store it in the formatter:
        auto it = ctx.begin(), end = ctx.end();
        if (it != end && (*it == 'f' || *it == 'e')) presentation = *it++;

        // Check if reached the end of the range:
        if (it != end && *it != '}') fmt::detail::throw_format_error("invalid format");

        // Return an iterator past the end of the parsed range:
        return it;
    }

    // Formats the point p using the parsed format specification (presentation)
    // stored in this formatter.
    auto format(const point& p, format_context& ctx) const -> format_context::iterator {
        // ctx.out() is an output iterator to write to.
        return presentation == 'f'
            ? fmt::format_to(ctx.out(), "({:.1f}, {:.1f})", p.x, p.y)
            : fmt::format_to(ctx.out(), "({:.1e}, {:.1e})", p.x, p.y);
    }
};

int main(int argc, char** argv)
{
    
    point p = { 1, 2 };
    std::string s = fmt::format("{:f}", p);
    // s == "(1.0, 2.0)"
    cout << s << endl;

    return 0;
}

运行结果如下:

如果要扩展 多态类型:

#include <iostream>
#include <type_traits>
#include <fmt/format.h>
using namespace std;

struct A {
    virtual ~A() {}
    virtual std::string name() const { return "A"; }
};

struct B : A {
    virtual std::string name() const { return "B"; }
};

template <typename T>
struct fmt::formatter<T, std::enable_if_t<std::is_base_of<A, T>::value, char>> :
    fmt::formatter<std::string> {
    auto format(const A& a, format_context& ctx) const {
        return fmt::formatter<std::string>::format(a.name(), ctx);
    }
};

int main(int argc, char** argv)
{
    
    B b;
    A& a = b;
    fmt::print("{}\n", b); // prints "B"
    fmt::print("{}\n", a); // prints "B"

    return 0;
}

 运行结果如下:

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值