【问题标题】:From parameter pack to var args从参数包到 var args
【发布时间】:2016-08-11 23:47:48
【问题描述】:

上下文:我在处理遗留代码,虽然我想慢慢地使这个代码达到 c++14 标准,但我仍然坚持使用 printf 之类的函数。 因此这种代码(简化):

 #include <iostream>
 #include <string>
 #include <cstdio>

 template <typename... Args>
 const char* Format(const char* strFormat, Args... args)
 {
   static char szBuffer[10000];

   auto len = std::vsnprintf(szBuffer, 10000, strFormat, args...);

   if (len < 0 || 10000 <= len)
   {
     szBuffer[0] = 0;
   }

   return szBuffer;    
 }

 int main()
 {
   auto test = Format("%s %s %d", "test", "test", 42);
 }

这奇怪地不起作用:gcc&VS2013 无法从扩展参数包转到 va_arg。 (http://cpp.sh/4aue)

10:66: error: cannot convert 'const char*' to '__va_list_tag*' for argument '4' to 'int vsnprintf(char*, size_t, const char*, __va_list_tag*)'

为什么会出现这种行为? 同时奇怪的是中间 var_arg 函数编译和工作正常 (http://cpp.sh/2ggms)。

谢谢

【问题讨论】:

    标签: c++ c++11


    【解决方案1】:

    你想要snprintf,而不是vsnprintf。参数包扩展为逗号分隔的列表。这些函数的v 版本只接受va_list

    在查看您的代码示例时,如果您打算传递 std::string,您仍然需要像 transform_to_c 这样的函数。

    旁注:您应该考虑此代码是否需要是线程安全的或可重入的。使用静态缓冲区意味着两者都不是。

    【讨论】:

    • 专注于模板扩展可能出现的问题,我完全忽略了 v/snprintf 错误...谢谢,是的,目标是参数检查!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-10-24
    • 2019-07-14
    • 1970-01-01
    • 2021-01-27
    • 2018-10-21
    • 2013-06-22
    相关资源
    最近更新 更多