2

我遇到了格式化用户定义类型的问题,最终得到了这个基于 fmt 文档的简单示例。

struct point_double {
    double x, y;

    operator const char*() const {
        return nullptr;
    }
};

namespace fmt {
template <>
struct formatter<point_double> {
    template <typename ParseContext>
    constexpr auto parse(ParseContext& ctx) {
        return ctx.begin();
    }

    template <typename FormatContext>
    auto format(const point_double& p, FormatContext& ctx) {
        return format_to(ctx.out(), "({:.1f}, {:.1f})", p.x, p.y);
    }
};
}  // namespace fmt

void foo() {
    point_double p = {1, 2};
    fmt::print("{}\n", p);
}

调用foo将崩溃,因为未使用用户定义的格式化程序。而是fmt::print使用默认的字符串格式化程序并在操作符返回时崩溃nullptr。有没有办法解决这个问题?我正在使用 fmt 5.3.0

4

1 回答 1

1

您不能同时进行隐式转换const char*和特化formatter({fmt} 现在会给您一个编译时错误),因为const char*它已经是可格式化的。如果您可以控制point_double,一个简单的解决方案是使转换运算符显式,这通常是一个好主意。否则,您可以包装point_double另一种类型并为此提供formatter专业化。

于 2019-07-27T06:49:31.557 回答