传递参数的个数变量num另一个方法

问题描述:

我有以下(简化例如用途)的代码,它的工作原理:传递参数的个数变量num另一个方法

void log(const string type, const string msg, va_list argp) 
{ 
    fprintf(stdout, "[%s] ", type.c_str()); 
    vfprintf(stdout, msg.c_str(), argp); 
} 

void log_err(const string msg, ...) 
{ 
    va_list argp; 

    va_start(argp, msg); 
    log("ERROR", msg, argp); 
    va_end(argp); 
} 

我会用它这种方式:

log_err("test: %d", 5); 

但是,如果我想将其移动到类:

class Logger { 
public: 
    Logger() { 
     // 
    }; 
    void generic(const string type, const string msg, va_list argp) { 
     fprintf(stdout, "[%s] ", type.c_str()); 
     vfprintf(stdout, msg.c_str(), argp); 
    }; 
    void error(const string msg, ...) { 
     va_list argp; 

     va_start(argp, msg); 
     this->generic("ERROR", msg, argp); 
     va_end(argp); 
    }; 
}; 

然后我得到分段错误。我知道像va宏这样的棘手的东西不能在类范围内工作,但我想知道为什么。

感谢您的建议!

编辑

用法示例:

Logger logger; 
logger.error("test", 5); 

完整的源:

#include <string> 
#include <cstdlib> 
#include <cstdarg> 

using namespace std; 

void log(const string type, const string msg, va_list argp) 
{ 
    fprintf(stdout, "[%s] ", type.c_str()); 
    vfprintf(stdout, msg.c_str(), argp); 
} 

void log_err(const string msg, ...) 
{ 
    va_list argp; 

    va_start(argp, msg); 
    log("ERROR", msg, argp); 
    va_end(argp); 
} 

class Logger { 
    public: 
     Logger() { 
      // 
     }; 
     void generic(const string type, const string msg, va_list argp) { 
      fprintf(stdout, "[%s] ", type.c_str()); 
      vfprintf(stdout, msg.c_str(), argp); 
     }; 
     void error(const string msg, ...) { 
      va_list argp; 

      va_start(argp, msg); 
      this->generic("ERROR", msg, argp); 
      va_end(argp); 
     }; 
}; 

int main() 
{ 
    //log_err("test: %s\n", "str"); 

    Logger logger; 
    logger.error("test %s", 5); 

    return 0; 
} 

我不想让这些方法静态的,因为在原来使用我有私人的文件描述符我正在写日志消息;

+2

了可变参数模板吗? – sehe 2012-03-25 20:29:47

+0

你粘贴的代码看起来很好。分段故障发生在哪里? “错误”的调用是什么样的? (并且摆脱'this->',这是不需要的。) – 2012-03-25 20:35:40

+0

你怎么实际调用'error()'?有关类和可变参数的'棘手'的事情是,你不能在变量参数列表中传递非POD对象。 – 2012-03-25 20:36:17

bug是这一行:

 logger.error("test %s", 5); 

%s格式说明是C风格的字符串。 5不是C风格的字符串。用途:

 logger.error("test %s", "5"); 

或:

 logger.error("test %d", 5); 
+0

哇!有效!我已经溜过了这么明显的事情,谢谢大卫! – 2012-03-25 21:53:00

+0

@ SebastianSito:如果您使用的是GCC,您可以使用'printf()'样式格式字符串标记该函数,并让编译器警告您这样的问题。就像:'__attribute__((format(printf,2,3)))'会做的伎俩(我认为)。有关详情,请参阅http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html – 2012-03-25 23:00:02

你在这里的99%。改变

void generic(const string type, const string msg, va_list argp) 

void generic(const string type, const string msg, va_list & argp) 

看来你不能复制名单(它是没有参照执行)

编辑::我上面贴错了。第一次通过我只是假设提供了seg故障,没有参考没有测试。我删除了参考和一切印刷得很好。

留给未来的人。

+0

所以你告诉我,上面的例子适合你?你可以粘贴你的代码以及复合标志吗? – 2012-03-25 21:12:59