宏C ++问题__VA_ARGS__

时间:2010-04-30 13:51:12

标签: c++ macros

这样的C ++宏使用有哪些(如果有的话)? 内联函数是否会更合适?

#define EVENT_INFO(_format_, ...) CMyEvent::Generate(__FILE__, __LINE__, CMyEvent::EVT_HIGH, _format_, __VA_ARGS__)

void
CMyEvent::Generate(
    const char* file,                      // filename
    int line,                              // line number
    CMyEvent::LEVEL level,                 // severity level
    const char *format,                    // format of the msg / data
    ...)                                   // variable arguments
{
    // Get a message from the pool
    CMyEvent* p_msg = GetMessageFromPool();
    if(p_msg != NULL)
    {
        va_list arguments; // points to each unnamed argument
        va_start(arguments, format);
        // Fill the object with strings and data.
        p_msg->Fill(file, line, level, 0, format, arguments);
        va_end(arguments);
    }
}

3 个答案:

答案 0 :(得分:1)

如果您可以重写消息以使用运算符<<(),也许使用带有自定义流缓冲区的std :: ostreams,您将不需要变量参数或丑陋(恕我直言)宏,它看起来像更像是C ++而不是C。

答案 1 :(得分:1)

当您使用C ++时,您可以避免使用可能存在许多问题的变量参数列表的缺陷:

  • 不检查参数数量
  • 不检查参数类型

要使其更多C ++,请执行以下操作:

#define EVENT_INFO(args) EventLogStream (__FILE__, __LINE__, __PRETTY_FUNCTION__) << args

并调用它(警告:这里的所有代码都是伪代码,可能在语法上不正确,但你应该得到基本的想法):

EVENT_INFO ("The answer to " << the_question << " is " << answer); // usually 42

EventLogStream类似于cout对象,就像cout一样,你可以提供类特定的输出:

class Vector3D
{
   EventLogStream &operator << (EventLogStream &out) { out << "{" << x << ", " << y << ", " << z << "}"; }
}

答案 2 :(得分:0)

variadic宏非常适合用于日志记录。比使用iostreams要好得多。除非您愿意手动传递__FILE____LINE__,否则内联函数将无效。

您可以用括号括起格式以确保安全(不需要恕我直言)