我有一个功能:
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个给定”。 有什么想法吗?
答案 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);
}