2

我有一个标题,它为我的自定义类型定义了所有 {fmt} 格式化程序。

为了缩短编译时间,我想减少这个自定义格式化程序头的依赖关系,并决定将所有格式化程序定义为外部模板,其中实现放在 a.cpp中,头文件中的声明如下:

template<>
struct formatter<MyType> : formatter<std::string>
{
  auto format(const MyType& t, format_context& ctx);
};

extern template struct formatter<MyType>;

...以及.cpp文件中的定义:

auto formatter<MyType>::format(const MyType& t, format_context& ctx)
{
  return format_to(ctx.out, "MyType: {}", ...);
}

主要优点是头文件变得不那么繁重,所有自定义类型都可以前向声明,并且我不再包含世界,以防我想在某个翻译单元中自定义单一类型的格式。

但是,大多数使用 {fmt} 实现自定义格式化程序的示例将format()函数定义为模板化format_context类型的模板函数:

template<typename FormatContext>
auto format(const MyType& t, FormatContext& ctx);

这实际上不适用于外部模板,因为我需要预先声明format()所有可能的类型FormatContext。这很容易出错。目前,只有使用fmt::format_context作品和编译器会告诉我什么时候它不再足够了。

我想知道由于没有在FormatContext类型上模板化格式函数而失去了什么?在什么情况下是fmt::format_context不够的?有没有更好的方法来定义这些自定义类型格式化程序,而不必将完整的实现放在头文件中?我正在考虑走这std::ostream条路,然后简单地包括<fmt/ostream.h>每当我想用 {fmt} 格式化我的类型时,但它首先部分地违背了使用 {fmt} 的目的。

4

1 回答 1

2

由于没有在 FormatContext 类型上模板化格式函数,我失去了什么?

您将失去通过输出迭代器进行格式化的能力。以前这意味着您将无法使用 format_to[_n]. 但是,在当前,master此限制已被删除,并且两者都可以 format_to与. 现在只有格式字符串编译可能需要自定义输出迭代器。format_to_nformat_context

于 2020-07-25T23:59:24.563 回答