变长参数函数调用变长宏

8

我有一个内联变参函数:
inline int foo(...)
我需要让foo()调用一个宏(假设叫做MACRO),这个宏也是变参的。基本上,我需要让foo()将其所有输入参数传递给MACRO。 重新定义foo()作为另一个宏是一种简单的解决方法,因为有__VA_ARGS__选项,但是我还需要foo()返回一个值。
注意:我试图在已经编写好的代码两个部分之间进行接口,我不被允许更改它们。 foo(...)在代码的第一部分中使用,而MACRO在第二部分中定义。我唯一要做的就是定义一个foo(),它使用MACRO,但我不能做到这一点,因为它们都是变参的。


你能否使用可变参数模板来替代省略号在 foo 函数中吗? - Jarod42
你是在说可变参数还是可变函数模板?一个可以解决你的问题,而另一个则不能。 - Quentin
4
无法完成。函数参数在运行时设置,宏在编译之前展开。我会放弃这个混乱的做法,并想办法以明智的方式完成它所要尝试的任务。 - Mike Seymour
先生,我不熟悉可变参数模板,请让我查一下。 - lulijeta
是的,我可以为foo使用可变参数模板,但当我将输入参数传递给可变宏时,我无法使其编译通过。 - lulijeta
你能展示一下 MACRO 吗?它的替换是否会因为 args... 而出现问题? - Jarod42
2个回答

7

foo定义为一个包含返回值的lambda表达式的宏,然后调用该lambda表达式。

#define foo(...) \
  [&](auto&&...args){ \
    /* do something with args, or __VA_ARGS__ */ \
    MACRO(__VA_ARGS__); \
    return 7; \
  }(__VA_ARGS__)

现在,int x = foo(a, b, c); 将会调用 foo 内部的 lambda 表达式,并在该 lambda 表达式内部调用 (a, b, c) 上的宏,然后返回一个值。

我为下一个维护你代码的人感到遗憾。


1
请注意,args...__VA_ARGS__在以下两种情况下可能不同:foo(arg1, (extra, parenthesis, around, comma, operator, arg2));或简单的foo(function_with_side_effect()) - Jarod42
1
@Jarod42 是的! auto&&....args(__VA_ARGS__) 是可选的,可能会导致不可预测的副作用。但是,它将参数作为参数以及令牌提供给您,这正是我认为 OP 想要的。 - Yakk - Adam Nevraumont

2
你所要求的是不可能的。
可变参数函数的参数在运行时确定,但宏在编译时展开。

4
不可能?这是C++。 - Yakk - Adam Nevraumont
@Yakk,这是不可能的。请再次阅读他的问题。foo需要是一个函数,而不是宏。 - orlp
因为 foo 必须返回一个值。所以我们只需要一个返回值的宏定义!在火星日食期间献祭三只处女山羊,明天早上给我打电话。或者,你知道的,在 C++ 代码中召唤可怕的生物也可以。两种方法都行。 - Yakk - Adam Nevraumont

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接