繁体   English   中英

fmt with Howard Hinnant 的日期:为什么来自 fmt::to_string 的“{}”? fmt 和日期的最佳实践?

[英]fmt with Howard Hinnant's date: why “{}” from fmt::to_string? Best practice for fmt and date?

TL;DR:我正在为fmt和 Howard Hinnant 的日期库实现自定义格式化程序。 date::year_month_day d{}; ,为什么fmt::to_string(d)返回"{}"fmt::format("{}", d)工作正常,返回"0000-00-00" Godbolt 上的示例


我正在使用日期库并尝试从 iostreams 切换到fmt 我需要将date::year_month_day为 YYYY-MM-DD 格式,因此我编写了一个自定义格式化程序( fmt::formatter for date::year_month_day的模板专业化):

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

Godbolt 上提供了完整的最小工作示例,其中包含两个工作示例和一个失败示例。

使用该自定义格式化程序, fmt::format("{}", date::year_month_day{})按预期工作,返回"0000-00-00" fmt::to_string(date::year_month_day{})应该返回相同的结果,但返回"{}"

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

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

更新:对自定义空结构使用自定义格式化程序可以正常工作,对format("{}", s)to_string(s)给出相同的结果,请参阅上面的 Godbolt 链接上的示例。 所以date::year_month_day一定有什么特别之处,它打破了fmt::to_string()

这是依赖于参数的查找的不幸影响: fmt::to_string调用format最终被解析为date::format而不是fmt::format 修复方法是完全限定fmt::to_string中对format的调用,因为它依赖于用户定义的类型。

更新:这已在https://github.com/fmtlib/fmt/commit/2cac8a9d2e36cd920a9a60ec5b776c187e843fbb中修复。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM