fmt和霍华德·辛南特(Howard Hinnant)的日期:为什么使用fmt :: to_string中的“ {}”? fmt和日期的最佳做法?

问题描述 投票:1回答:1

TL; DR:我正在为fmt和Howard Hinnant的date库实现自定义格式化程序。使用date::year_month_day d{};时,为什么fmt::to_string(d)可以返回"{}",而fmt::format("{}", d)可以正常工作,返回"0000-00-00"Example on godbolt


我正在使用date库,并尝试从iostream切换到fmt。我需要将date::year_month_day格式化为YYYY-MM-DD格式,所以我写了一个自定义格式化程序(date::year_month_day的fmt :: formatter模板专用化):

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

    template<typename FormatContext>
    auto format(const date::year_month_day & ymd, FormatContext & ctx) -> decltype(ctx.out()) {
        const int year = (int)ymd.year();
        const unsigned month = (unsigned)ymd.month();
        const unsigned day = (unsigned)ymd.day();
        return fmt::format_to(ctx.out(), "{:04}-{:02}-{:02}", year, month, day);
    }
};

完成最小工作示例,其中有两个工作示例,其中一个失败,是available on godbolt

使用该自定义格式器,fmt::format("{}", date::year_month_day{})可以正常工作,返回"0000-00-00"fmt::to_string(date::year_month_day{})应该返回相同的结果,但是返回"{}"

date::year_month_day格式化date和其他类型,包括fmt的最佳方法是什么?为什么我得到那个fmt::to_string()

我还不能使用具有C ++ 20日期支持的编译器:据我所知,截至2020年6月,还没有C ++ 20 std :: chrono的日历和时区部分的完整实现。

更新:对自定义的空结构使用自定义格式化程序可以很好地工作,对"{}"format("{}", s)给出相同的结果,请参见上面的Godbolt链接上的示例。因此,to_string(s)必须有一些特殊之处,它会破坏date::year_month_day

c++ date chrono fmt
1个回答
0
投票
这是依赖于参数的查找的不幸结果:fmt::to_string()调用fmt::to_string,最终将其解析为format而不是date::format。解决方法是完全限定对fmt::format中的format的调用,因为它取决于用户定义的类型。
© www.soinside.com 2019 - 2024. All rights reserved.