c++ clang,fmtlib编译问题

dwbf0jvd  于 12个月前  发布在  其他
关注(0)|答案(1)|浏览(141)

我刚刚升级了我们的代码库,使用fmt 10,并已进入一个奇怪的问题。
Fmt引入了format_as作为一种为你自己的枚举/类添加自定义格式化程序的简单方法,还引入了std::optional的格式化。
然而,这两种方法的组合使用clang编译失败,但使用gcc或msvc编译良好。一个例子可以在这里找到:godbolt。将编译器更改为gcc,代码编译良好。

#include <fmt/format.h>
#include <fmt/std.h>
#include <optional>

namespace nn
{

enum class Bar
{
    First,
    Second,
    Third,
    Fifth = 5,
};

std::string_view format_as(Bar bar)
{
    switch (bar) {
    case Bar::First:
        return "One";
    case Bar::Second:
        return "Two";
    case Bar::Third:
        return "Three";
    case Bar::Fifth:
        return "Five";
    }
    return "";
}
}

int main() {
    auto b = nn::Bar::First;
    std::optional<nn::Bar> ob = b;
    

    fmt::print("{} {}\n", b, ob);

    return 0;
}

字符串
问题似乎是“fmt/std. h”在第170行调用u.set_debug_format(set);,而set_debug_format是私有的,因为fmt/format. h第4055行中的私有继承。如果我在第4058行添加using base::set_debug_format;,代码也会在clang上编译。
有没有其他人遇到过这个问题?是fmt中的bug,还是clang编译器的问题,还是我做错了什么?

q5iwbnjs

q5iwbnjs1#

是的,这是clang中的一个bug,在https://github.com/llvm/llvm-project/issues/68849中报告过。正如在https://github.com/scylladb/seastar/pull/1855中讨论的,解决方法是从基本格式化程序中公开继承;在您的情况下:

template<>
struct fmt::formatter<nn::Bar> : fmt::formatter<std::string_view> {
    using base = fmt::formatter<std::string_view>;
    auto format(nn::Bar b, auto& ctx) const { return base::format(format_as(b), ctx); }
};

字符串
Demo的函数。
请注意,这会将输出从optional(One)更改为optional("One"),因为对公共继承的更改将允许parse调用base::set_debug_format();但是,这对于fmt来说无疑是更可取的行为。

相关问题