函数重载的变量宏

时间:2015-12-10 09:26:13

标签: c++ macros overloading variadic-functions variadic-macros

我有一个功能:

SendMsg(int x, string y, ...) { /*some code*/ }

我有一个宏:

FOO(X, STRING, ...) SendMsg(X, STRING "%s %d", ##__VA_ARGS__, "xyz", 123)

所以我可以这样:

FOO(1000, "Note that line %d containing %d words is invalid", 5, 10);

扩展到

SendMsg(1000, "Note that line %d containing %d words is invalid" "%s %d", 5, 10, "xyz", 123);

有时我会这样:

FOO(1000, "String without variables");

应该扩展为

SendMsg(1000, "String without variables" "%s %d", "xyz", 123)

到目前为止宏工作正常。

但有时我会有这样的事情:

FOO(1000);

应该扩展为

SendMsg(1000, "%s "%d", "xyz", 123);

但这不起作用。我得到一个错误,“宏FOO需要3个参数,但只有1个给定”。 有什么想法吗?

2 个答案:

答案 0 :(得分:0)

您需要做的是更改SendMsg的签名。

SendMsg(int x, char *secondFmt, char *xyx, int no123, ...)
{
     // Print the string in buffer with ##__VA_ARGS__ using sprintf. first 
     // argument extracted from will be string only. otherwise sprintf will fail
     va_start(args, no123);
     const char *fmt = va_arg(args, const char *);
     bytesWrote = sprintf(buffer, fmt, args);
     sprintf(buffer + bytesWrote, secondFmt, xyz, no123);
     va_end(args);
}

现在Foo看起来像

FOO(X, ...) SendMsg(X, "%s %d", "xyz", 123, ##__VA_ARGS__)

我所做的是先从##__VA_ARGS__打印消息然后再打"%s %d"部分消息。如何以相反的顺序向SendMsg提供参数。未经测试,所以只需调整代码。

如果您不想修改SendMsg,请查看以下代码是否有效。

 FOO(X, ...) {\
  va_start(args, no123);\
  const char *fmt = va_arg(args, const char *);\
  SendMsg(X, fmt "%s %d", "xyz", 123, args);\
  va_end(args);\
}\

如果没有,只需编写两个宏:

FOO_FMT(X, STRING, ...) SendMsg(X, STRING"%s %d", "xyz", 123, ##__VA_ARGS__)
FOO(X) SendMsg(X, "%s %d", "xyz", 123)

答案 1 :(得分:0)

使用可变参数模板(C ++ 11),您可能会执行重载,例如:

template <typename... Ts>
void FOO(int x, const std::string& format, Ts... args)
{
    SendMsg(x, format + "%s %d", args..., "xyz", 123);
}

void FOO(int x)
{
    SendMsg(x, "%s %d", "xyz", 123);
}

Demo