简体   繁体   English

将可变参数函数参数转发给另一个可变参数函数而无需成本

[英]Forward variadic function arguments to another variadic function without cost

I have a variadic function LogDebug for log writing. 我有一个可变函数LogDebug用于日志写入。 Logging happens in two modes. 记录以两种模式进行。 My application forwards variadic arguments to another variadic function LogDebugEx in most cases hence that path needs to optimize. 我的应用程序在大多数情况下将可变参数转发给另一个可变参数函数LogDebugEx ,因此该路径需要优化。 To be specific it takes 38% for vsnprintf for some of my requests on callgrind graph. 具体来说,对于我在callgrind图上的一些请求, vsnprintf需要38%。 Please note that this function called many times for a single request. 请注意,此功能可针对单个请求多次调用。

void LogDebug(const char* zFormat, ...)
{
    char zDesc[5000];
    va_list ap;
    va_start(ap, zFormat);
    vsnprintf(zDesc, 5000, zFormat, ap);  // Need to optimize in remode mode.
    va_end(ap);

    if (m_logMode == LOG_MODE_LOCAL)    // Does not need to optimize this mode.
    {
        // This mode is not interested.
    }
    else // m_logMode == LOG_MODE_REMOTE, critical path
    {
        LogDebugEx("%s", zDesc);   // Forwarded to new variadic function
    }
}

Question : I need to avoid copying whole argument list to zDesc array before forwarding to LogDebugEx function. 问题 :在转发到LogDebugEx函数之前,我需要避免将整个参数列表复制到zDesc数组。 Is there a way i can perfect forward variadic arguments coming to LogDebug into LogDebugEx function? 有没有办法可以完美地将可变参数传递给LogDebugLogDebugEx函数?

Any other fancy way to do this would also be fine without changing function calls to LogDebug . 如果不改变对LogDebug函数调用,任何其他奇特的方法也可以。 I have C++11 supported compiler GCC 4.9.3 . 我有C++11支持的编译器GCC 4.9.3

If we have c++11, why mess around with variadic argument lists? 如果我们有c ++ 11,为什么要乱用可变参数列表呢?

#include <utility>

extern enum {LOG_MODE_LOCAL, LOG_MODE_REMOTE} m_logMode;

extern void LogDebugEx(const char*, ...);

template<class...Args>
void LogDebug(const char* zFormat, Args&&...args)
{

    if (m_logMode == LOG_MODE_LOCAL)    // Does not need to optimize this mode.
    {
        char zDesc[5000];
        snprintf(zDesc, 5000, zFormat, args...);  
        // do what you have to do here
    }
    else // m_logMode == LOG_MODE_REMOTE, critical path
    {
        LogDebugEx(zFormat, std::forward<Args>(args)...);   // Forwarded to new variadic function
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM