C++ fmtlib:如何利用内置格式规范解析来输出自定义类型?

2nbm6dog  于 2023-03-14  发布在  其他
关注(0)|答案(1)|浏览(438)

这与使用fmtlib c++库有关。
我有一个模板化的有理类型,它包含一个分子和分母,我通过专门化fmt::formatter来格式化它,如文档中所述。我希望接受整型所接受的相同格式规范,而不必显式地编写代码来解析该规范。
基于文档,我发现我可以从fmt::formatter<int>派生出fmt::formatter的特殊化,它将处理规范的解析,这很棒。在文档示例中,然后调用格式化程序的底层format方法来处理输出。然而,在我的示例中,我需要格式化两个用/分隔的值。
如何利用底层格式化程序来格式化分子和分母?

更新日期:

下面的格式化程序专门化完成了基本工作,如果q不为1,则以p/q输出数字,如果q为1,则以p输出数字,并将格式化规范应用于p,这并不完全是我所希望的工作方式。我希望格式字符串中指定的宽度应用于整个输出,而不仅仅是分子,但我不知道该如何处理这些信息。

template<rational::Rational T> struct fmt::formatter<T>
    : fmt::formatter<typename T::numerator_type> {
    using base_type = fmt::formatter<typename T::numerator_type>;
    template<class FormatContext>
    auto format(const T& r, FormatContext& ctx) {
        auto n = r.num();
        auto d = r.den();
        if (d == 1)
            return base_type::format(n, ctx);

        base_type::format(n, ctx);
        return format_to(ctx.out(), "/{}", d);
    }
};
pod7payv

pod7payv1#

由于希望将宽度应用于整个输出,因此需要在formatter::parse函数中自己解析它,然后在需要时将其余部分委托给元素格式化程序。(例如fmt::memory_buffer),然后将结果复制到用填充字符填充的输出中。计时格式化程序就是这样做的。2如果没有指定宽度,额外的副本可以省略。
一旦范围的格式支持宽度,你就可以用一种更简单的方式来实现它,即重用一个范围格式器,用/作为分隔符,并使用空分隔符。

相关问题