我有点不喜欢 fmt(及其
std
变体)的现有 API 来为不同类型自定义格式化程序:
std::formatter
命名空间内专业化 foo
)也许我错过了一些东西,但编写临时解决方案比找到预期的解决方案更容易(如果有的话......)。
下面是一个工作示例,但我很高兴看到更干净的示例。
使用包装器模板的最简单且幼稚的解决方案。 Lambda 保证具有唯一的类型,因此有无数种方法可以格式化一种类型。
我这里没有提供
parse
接口,因为我认为它相当多余。#include <format>
template <typename T, typename Format>
struct in_place_formatter{
const T &value;
Format format;
};
template <typename T, typename Format>
in_place_formatter(const T&, Format) -> in_place_formatter<T, Format>;
template <typename T, typename Format, typename Char>
struct std::formatter<in_place_formatter<T, Format>, Char> {
constexpr auto parse(std::format_parse_context &ctx) { return ctx.begin(); }
constexpr auto format(const in_place_formatter<T, Format> &uf, std::format_context &ctx) const {
return uf.format(uf.value, ctx);
}
};
#include <iostream>
int main() {
struct {} john_cena;
std::cout << std::format("And his name is... {}\n",
in_place_formatter{john_cena,
[](const auto&, std::format_context &ctx)
{
return std::format_to(ctx.out(), "{}", "John Cena");
}});
std::cout << std::format("{}\n",
in_place_formatter{john_cena,
[](const auto&, std::format_context &ctx)
{
return std::format_to(ctx.out(), "{}", "You can't see me");
}});
return 0;
}