自定义 {fmt} 格式化程序和外部模板,有什么缺点吗?

3

我有一个头文件,用于定义我自己类型的所有{fmt}格式化程序。

为了提高编译时间,我希望减少这个自定义格式化程序头文件的依赖关系,并决定将所有格式化程序定义为外部模板,其中实现放在.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);

由于我需要预先声明所有可能类型的FormatContext,因此它实际上无法与外部模板一起使用。这很容易出错。目前只能使用fmt::format_context,如果不够用编译器会告诉我。

我想知道如果没有针对FormatContext类型的格式函数模板化,会失去什么?在哪些情况下fmt::format_context不足够?有没有更好的方法来定义这些自定义类型格式化程序,而不必将完整实现放在头文件中?我在考虑采用std::ostream的方式,然后只需在需要使用{fmt}格式化我的类型时包含<fmt/ostream.h>,但这在一定程度上违背了使用{fmt}的初衷。

1个回答

2
如果没有基于“FormatContext”类型的格式化函数模板,你将失去通过输出迭代器进行格式化的能力。以前这意味着你将无法使用“format_to[_n]”。但是在当前的“master”版本中,这种限制已经被移除,现在“format_to”和“format_to_n”都可以使用“format_context”。现在只有“格式字符串编译”可能需要自定义输出迭代器。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接