个人技术分享

之前为了实现可变参数费老脖子劲了,要写一堆的东西,记得当初为了研究可变参数,硬是把log4cxxx研究了一遍,直到看到这样的代码:

template<typename FormatString, typename... Args>
inline void error(const FormatString &fmt, const Args &... args)
{
	fmt::print(fmt, args...);
}
template <typename S, typename... Args>
inline FMT_ENABLE_IF_T(internal::is_string<S>::value, void)
    print(std::FILE *f, const S &format_str, const Args &... args) {
  vprint(f, to_string_view(format_str),
         internal::checked_args<S, Args...>(format_str, args...));
}

fmt::print(fmt, args...); 这种语法是C++11引入的可变参数模板 (variadic templates)。这是一个函数模板,可以接受任意数量和类型的参数,并将它们传递给fmt::print函数。

可变参数模板 (Variadic Templates)

可变参数模板允许定义参数数量可变的模板。这在C++11中被引入,提供了更灵活的函数和类模板定义方式。

  • template<typename FormatString, typename... Args>: 这是模板参数列表,表示该模板可以接受一个类型FormatString和任意数量、任意类型的参数Args
  • const Args& ... args: 这是函数参数列表,表示该函数可以接受任意数量的参数args,每个参数的类型由Args推导得出。

具体到 fmt::print(fmt, args...) 的解释

在函数体内,fmt::print(fmt, args...) 调用了fmt库的print函数,传递了格式化字符串fmt和展开后的参数包args...

fmt::print 函数的模板定义

第二个代码片段定义了一个名为 print 的模板函数,它使用了 SFINAE(Substitution Failure Is Not An Error)技术和条件模板以确保函数只有在满足特定条件时才被实例化。

  • FMT_ENABLE_IF_T(internal::is_string<S>::value, void): 这是一种 SFINAE 技术,确保这个模板只有在 internal::is_string<S>::valuetrue 时才会实例化。internal::is_string 可能是一个用来检查模板参数 S 是否为字符串类型的类型特征。
  • const S& format_str: 这是一个字符串格式化参数。
  • const Args& ... args: 这是一个可变参数包,包含任意数量的格式化参数。

fmt::print 是什么?

fmt::printfmt 库中的一个函数,fmt 库是一个现代的 C++ 字符串格式化库,类似于 Python 的 str.formatprintf,但更为安全和强大。fmt::print 可以直接输出格式化后的字符串。

总结

fmt::print(fmt, args...) 这种语法是C++11引入的可变参数模板技术,用于创建参数数量可变的函数模板。在这个例子中,使用了 fmt 库来进行字符串格式化和输出。