如何通过 #define 函数向格式化字符串函数调用添加参数
我想创建将参数插入函数调用的宏。例如,我在下面声明了函数 Action()
。 Action 采用状态编号的枚举和带有可选字符串参数的格式化字符串作为输入。
我想定义宏,以便不用使用 ActionState1
作为状态参数调用 Action( ActionState1, "someText %d", &arg)
,我只需调用 < code>State1("someText %d", &arg) 相反。这样,宏就会粘在我的状态参数的 ActionState1
中。我正在考虑类似以下内容:
#define State1(formatedString, ...) Action(ActionState1, formatedString, ...)
#define State2(formatedString, ...) Action(ActionState2, formatedString, ...)
#define State3(formatedString, ...) Action(ActionState3, formatedString, ...)
enum {
ActionState1,
ActionState2,
ActionState3
}
static void Action( State state, String formatedString, ...);
有谁知道正确的格式是什么?
I want to create macros that will insert a parameter into a function call. For example, I have function Action()
declared below. Action takes as it's inputs an enum for the state number and a formatted string with optional args for the string.
I want to define macros so that instead of callingAction( ActionState1, "someText %d", &arg)
with ActionState1
for the state parameter, I can just call State1("someText %d", &arg)
instead. That way the macro would stick in the ActionState1
for the state param for me. I'm thinking of something like the following:
#define State1(formatedString, ...) Action(ActionState1, formatedString, ...)
#define State2(formatedString, ...) Action(ActionState2, formatedString, ...)
#define State3(formatedString, ...) Action(ActionState3, formatedString, ...)
enum {
ActionState1,
ActionState2,
ActionState3
}
static void Action( State state, String formatedString, ...);
Does anyone know what the proper format for this would be?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我相信
__VA_ARGS__
是您要查找的内容:这是一项 C99 功能,Wikipedia 声称它们不是任何官方 C++ 标准的一部分(我注意到这一点是因为您使用了 C++ 标签),而是一个相当流行的扩展。 这个问题有一些很好的讨论< /a>.
I believe that
__VA_ARGS__
is what you're looking for:This is a C99 feature, and Wikipedia claims that they are not part of any official C++ standard (I note this because you use the C++ tag), but a fairly popular extension. There is some good discussion over at this question.
不,这不能使用预处理器来完成。预处理器允许您将实体串起来,但不能反向操作。对于您想要的,您需要将
State1
分解为两个组件State
和1
(后者更重要),然后继续称呼。然而,更重要的问题是你为什么要这样做?通过这样的转换,您几乎无法节省任何打字或获得可读性。
不过,您可以使用模板在附近获得一些东西:
并将上面的内容用作:
但同样,IMO 这里几乎没有任何语法增益。
No this cannot be done using the preprocessor. The preprocessor allows you to string up entities but not go the reverse way. For what you want, you will need to break up
State1
to two componentsState
and1
(the latter being more important) and proceed with the call.However, the more important question is why would you want to do this? You hardly save any typing by such a transformation or gain readability.
You could get something nearby using templates though:
and use the above as:
But again, there's hardly any syntactic gain here IMO.
为什么要创造这样的东西?在 C++ 中,更喜欢使用流运算符或类似的操作符而不是使用可变参数,因为它除其他外还获得了类型安全性。
我不相信有任何方法可以在 C++ 预处理器宏中执行您想要的操作。如果你有一个 va_list 版本的 Action,你也许能够摆脱类似下面的内容,但我似乎记得
...
之前的参数必须是 POD - 不幸的是快速搜索无法证实或否认这一点。Why do you want to create such a thing? In C++ Prefer to use streaming operators or similar over using varargs as it gains type safety among other things.
I don't believe there's any way to do what you want in C++ preprocessor macros. If you had a va_list version of Action, you might be able to get away with something like the following, but I seem to recall that the parameter before the
...
must be POD - unfortunately a quick search can't confirm or deny that.