如何将可变函数参数传递给 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::format
,std::string_view
可能就足够了。 const std::string &
不酷,因为它强制进行堆分配。
另外,我不确定我对单独的无参数重载感觉如何。这意味着你必须转义 {
和 }
只有 当至少有一个参数时,这不好。
也可以考虑使用spdlog,非常相似。它包装了 libfmt,并且可以将输出定向到 various/arbirary 个目标。
我正在尝试编写一个记录器,它可以采用与 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::format
,std::string_view
可能就足够了。 const std::string &
不酷,因为它强制进行堆分配。
另外,我不确定我对单独的无参数重载感觉如何。这意味着你必须转义 {
和 }
只有 当至少有一个参数时,这不好。
也可以考虑使用spdlog,非常相似。它包装了 libfmt,并且可以将输出定向到 various/arbirary 个目标。