带有外部术语板的自定义类型{fmt}格式化程序,有什么缺点吗



我有一个头,它为我的自定义类型定义了所有{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预先声明format()。这很容易出错。目前,只有使用fmt::format_context才有效,编译器会告诉我什么时候它不再足够了。

我想知道如果没有在FormatContext类型上模板化格式化函数,我会损失什么?在什么情况下fmt::format_context是不够的?有没有更好的方法可以定义这些自定义类型格式化程序,而不必将完整的实现放在头文件中?我想走std::ostream路线,然后只要我想用{fmt}格式化我的类型,就简单地包括<fmt/ostream.h>,但这在一定程度上违背了最初使用{fmt]的目的。

如果没有在FormatContext类型上模板化格式化函数,我会失去什么?

您将失去通过输出迭代器进行格式化的能力。以前这意味着你将无法使用format_to[_n]。然而,在当前的master中,这种限制具有已删除,并且format_toformat_to_n都与CCD_ 16。现在仅格式化字符串编译可能需要自定义输出迭代器。

最新更新