c++ 转发函数调用
Posted
技术标签:
【中文标题】c++ 转发函数调用【英文标题】:c++ forward function call 【发布时间】:2017-05-15 09:36:46 【问题描述】:是否可以将一个函数的参数列表转移到另一个函数?
例如,在我的函数 A 中,我想使用可变参数列表中的参数调用我的函数 B/函数 C(取决于执行状态)。请注意,我无法更改 functionB/functionC 声明。
int functionA(int a, ...)
...
va_list listPointer;
va_start( listPointer, a);
...
int functionB(long b, long c, long d)
...
...
int functionC(long b, int c, int d)
...
...
对于这个项目,我使用 gcc 4.9.1。
到目前为止,我尝试的是从 listPointer 传递 void* 但它没有用...
从 va_list 中提取变量也不起作用,因为我有 80 个其他类似的函数应该从 functionA 调用,这意味着我无法提取参数并通过提取的值调用。
也许有一种方法可以复制 functionA 参数的内存并使用指向它的指针调用 functionB/functionC?有谁知道这怎么可能?
【问题讨论】:
在函数functionA
中从va_list listPointer
中读取它们,然后将它们按值传递给functionB
。还是出于某种原因不是故意的?
@StephanLechner 是的,原因在于,根据逻辑,我的 functionA 还可能调用具有不同参数类型的其他函数......这就是为什么显式提取参数不起作用......我会将其添加到我的问题中
Forward an invocation of a variadic function in C的可能重复
如果你想使用可变参数模板而不是 C 风格的可变参数函数,这很容易 ..
@M.M 抱歉,我的 c++ 不太好……你能给我一些关于这种方法的更多信息,甚至是一个简单的例子吗?
【参考方案1】:
如果您无法更改函数 B,则必须从 functionA
va 列表中提取参数:
#include <stdarg.h>
#include <stdio.h>
int functionB(long b, long c, long d)
return printf("b: %d, c: %d, d: %d\n", b, c, d);
int functionA(int a, ...)
...
va_list va;
va_start(va, a);
long b = va_arg(va, long);
long c = va_arg(va, long);
long d = va_arg(va, long);
va_end(va);
return functionB(b, c, d);
也许有一种方法可以复制 functionA 参数的内存并使用指向它的指针调用 functionB/functionC?有谁知道这怎么可能?
那么这意味着您必须更改functionB
、functionC
等的声明。您不妨将它们改为接受va_list
:
int functionA(int a, va_list args);
int functionC(int c, va_list args);
【讨论】:
感谢您的建议,但它不适用于我的情况,因为我有一个函数 C 也采用不同的参数...【参考方案2】:如果您的va_args
中只有longs
可以工作。
int functionA(int a, ...)
va_list listPointer;
va_start( listPointer, a);
long b = va_arg(listPointer, long);
long c = va_arg(listPointer, long);
long d = va_arg(listPointer, long);
va_end(listPointer);
return functionB(b, c, d);
【讨论】:
感谢您的建议,但它不适用于我的情况,因为我有一个函数 C 也采用不同的参数...【参考方案3】:你不能改变B的签名,但是你能改变A的签名吗? 如果是这样,这可能是一个不错的选择:
template <typename... Args>
int functionA(Args&& ... args)
return functionB(std::forward<Args>(args)...);
【讨论】:
是否保证只有functionA
的第2个到第4个参数被传递给functionB
?
@StephanLechner 我认为问题中暗示了调用者将为所选函数传递正确数量和类型的参数。否则无论如何都无法回答
在这种情况下没有。但如果签名更改为int functionA(int a, Args&& ... args)
,则可以。但是参数a
可以省略,因为我猜它只在OP 版本中用于确定提供了多少可变参数。在这种情况下,可以使用size_t v = sizeof(args...)
计算
MM 是对的,即为所选函数传递了正确的数字和类型。但是我的编译器没有 std::forward ...
@AksimElnik 然后您应该在问题中包含您的编译器名称和版本以上是关于c++ 转发函数调用的主要内容,如果未能解决你的问题,请参考以下文章
C++ Primer 5th笔记(chap 16 模板和泛型编程)转发
GroovyMOP 元对象协议与元编程 ( 使用 Groovy 元编程进行函数拦截 | 重写 MetaClass#invokeMethod 方法实现函数拦截 | 实现函数调用转发 )