c++ - 将可变模板参数传递给可变函数

标签 c++ c++11 variadic-templates variadic-functions perfect-forwarding

我们正在使用第三方 C 库,它提供了 printf() 风格的日志函数,

void log(const char *format, ...);

出于不值得深入探讨的原因,我们需要限制消息的记录速率,类似于

void rate_limited_log(const char* format, ...)
{
    if (<not too fast>) {
         log(format, ...);
    }
}

幸运的是,C 库的作者知道他们在做什么,并提供了

void logv(const char* format, va_list ap);

所以写上面的函数是一件比较简单的事情。然而不幸的是variadic functions don't play well with inlining ,所以我想到了第二个解决方案:

template <typename... T>
void rate_limited_log(const char* format, T&&... args)
{
    if (<not too fast>) {
        log(format, std::forward<T>(args)...);
    }
}

这完美地工作并且内嵌了我们想要的速率限制条件。但我对此有几个问题:

  • 在 C++11 中将参数包扩展到 C 风格的可变参数函数调用中是合法的、定义明确的事情,还是我们只是很幸运它能工作?

  • 鉴于我们调用的是 C 函数,&&std::forward 在这里真的是必需的吗?如果我使用 const T&,或者甚至只是按值使用 T,无论是否使用 std::forward,它似乎都一样有效。

最佳答案

将参数包扩展为可变参数是有效的。

而且想转发就转发也没有坏处。但是通过 const& 获取也传达了一些有用的信息。

传递给 ... 的值将经历“默认参数提升”。参见 http://en.cppreference.com/w/cpp/language/variadic_arguments

这些都不关心引用。

您可以改进您的代码。您可以检查 Ts... 是否是传递给打印例程的有效类型,既可以通过“类型类型”,也可以通过实际解析格式字符串和确认参数的数量(有时是类型) .如果失败,您可以记录错误消息而不是崩溃。

关于c++ - 将可变模板参数传递给可变函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25512630/

相关文章:

C++ 在类构造函数中定义一个常量成员变量

c++ - 如何在不收到编译器警告的情况下使用 C++ 枚举

c++ - 我哪里错了?我收到链接器错误( undefined symbol ),我被卡住了

c++ - constexpr 中的 "integer constant overflow"警告

c++ - 快速加权均值和方差10格

c++ - Unique_ptr 容器或 unique_ptr 元素

c++11 - 添加 llvm 指令

c++ - 为 C 回调包装器使用可变参数模板

c++ - 获取 std::function 的可变参数模板参数类型的自定义 sizeof

c++ - 使用模板化模板的多重继承