尝试将以下功能升级到C ++ 11时
int inline formatText(const char* const fmt, ...)
{
va_list args;
va_start(args, fmt);
int len = std::min(vsnprintf(m_text, m_textSize, fmt, args), m_textSize);
va_end(args);
m_text[len] = '\0'; // assume m_textSize is storage size - sizeof('\0')
return len;
}
显然,由于printf处理POD,因此该函数按值接受其参数并不是一个问题。
但我意识到我不清楚如何实现宏观的精确转发参数,我意识到通过内联这个简单版本的编译器可以消除传值,但我并不完全确定以下三种方法中哪一项在技术上最佳:
template<typename... Args>
#if defined(APPROACH_1)
int formatText(const char* const fmt, Args...)
#elif defined(APPROACH_2)
int formatText(const char* const fmt, const Args&...)
#else
int formatText(const char* const fmt, Args&&...)
#endif
{
int len = std::min(snprintf(m_text, m_textSize, fmt, std::forward<Args>(args)...);
m_text[len] = '\0';
return len;
}
因为我们在这里谈论printf,所以按值复制并不可怕,因为我不应该将它传递给非pod对象;指定const ref肯定会帮助我不想复制的复杂对象,但对于printf的正常使用情况显然会适得其反。我很清楚方法3的副作用是什么。
到目前为止我读过的所有内容都让我觉得'Args&amp;&amp; ...'可能是变参数模板的正常情况,但在这种情况下,我的直觉告诉我要采取方法# 1。