如何将可变函数参数传递给 C++ 中的另一个函数(特别是 std::format)?

How to pass variadic function parameters to another function in C++ (specifically std::format)?

我正在尝试编写一个记录器,它可以采用与 printf 支持格式相同的方式接收参数。我打算在我的记录器的输入上调用 std::format,但我需要将可变参数转发给 std::format。我该怎么做?

我也想要的样子:

void log(const std::string& msg)
{
  std::cout << msg << std::endl; // I'm actually wrapping another logger here, this is just an example.
}

void log(const std::string& fmt_string ...);
{
  std::string msg = std::format(gmt_string, ...);
  log(msg);
}

您需要使用 template parameter pack and std::forward,例如:

template <class... Args>
void log(const std::string& fmt_string, Args&&... args)
{
  std::string msg = std::format(fmt_string, std::forward<Args>(args)...);
  log(msg);
}

您不需要 C 风格的 ... 参数。你想要一个可变参数模板:

template <typename T, typename ...P>
void log(T &&format, P &&... params)
{
    std::string msg = fmt::format(std::forward<T>(format), std::forward<P>(params)...);
    std::cout << msg << '\n';
}

注意转发参数 pack 的引用,而不是 const 引用。 const 引用之前给我带来了问题(spdlog 曾经使用 const 引用,fmt::join 不喜欢它们)。

注意第一个参数被模板化。至少对于 libfmt,这是能够接收 FMT_STRING(...) 参数所必需的。对于 std::formatstd::string_view 可能就足够了。 const std::string & 不酷,因为它强制进行堆分配。

另外,我不确定我对单独的无参数重载感觉如何。这意味着你必须转义 {} 只有 当至少有一个参数时,这不好。

也可以考虑使用spdlog,非常相似。它包装了 libfmt,并且可以将输出定向到 various/arbirary 个目标。