Проблема с форматированием пользовательских типов в библиотеке fmt

Я столкнулся с проблемой форматирования пользовательского типа и закончил этим простым примером на основе документации 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

1 ответ

Решение

Вы не можете иметь неявное преобразование в const char* и formatter специализация (теперь {fmt} даст вам ошибку во время компиляции), потому что const char* уже форматируется. Если у вас есть контроль над point_doubleпростое решение - сделать оператор преобразования явным, что в целом является хорошей идеей. В противном случае вы можете обернуть point_double в другом типе и обеспечить formatter специализация для этого.

Другие вопросы по тегам