使用varargs参数的C ++泛型函数调用 [英] C++ generic function call with varargs parameter
问题描述
在我的项目中,我有不同数量的输入参数和不同类型的函数。由于这些功能是图书馆的一部分,我无法改变他们的定义或机构。
void methodA(boolean p1,int p2,long p3){
...这里有些不相关的代码.. 。
}
void methodB(int p1,int p2,int p3,long p4){
...这里有些不相关的代码...
}
int methodC(long p4){
...
}
在我的项目中,我需要一个方法,它将接收其中一个函数的地址。此外,它还接收完整的参数列表(适合第一个参数中的功能)。然后这个方法必须使用传递的参数调用传递的函数。
现在我有了:(我简化了一些代码,使我的想法变得清晰)
void intercaller(void * some_func_address,...){
// VARARGS parameters extractor
va_list listPointer;
va_start(listPointer,some_func_address);
int p1 = va_arg(listPointer,int);
int p2 = va_arg(listPointer,int);
int p3 = va_arg(listPointer,int);
long p4 = va_arg(listPointer,long);
$ b $ // TODO:这不是通用调用,只能调用方法B
((void(*)(int,int,int,long))some_func_address)(p1,p2, p3,p4);
va_end(listPointer);
}
我的问题是实际的函数调用。函数调用中的参数列表应该是泛型的,应该能够包含不同数量的参数,可惜我不知道该怎么做......我尝试过在这里传递可变参数列表:
((void(*)(va_list))some_func_address)(listPointer);
但是这会扰乱被调用函数中的参数...
所以我的问题是:有没有一种方法以通用的方式调用给定的参数给定的参数?也许我需要某种typedeff或包装函数?
如果您没有
std :: invoke 然而,使用可变参数模板 。要很好地处理 void
函数,请使用 SFINAE 。 模板< typename R,typename ... Args>
auto call(R(* function)(Args ...),Args ... args) - > typename std :: enable_if<!std :: is_same< R,void> :: value,R> :: type {
return function(args ...);
}
模板< typename ... Args>
void call(void(* function)(Args ...),Args ... args){
function(args ...);
$ / code>
示例:
void a(){
std :: cout<< '一个';
}
void b(int a){
std :: cout<< b:<<一个;
}
int c(int a){
return a;
}
int main(){
call(a);
call(b,1);
std :: cout<< c:<<致电(c,2);
}
不要忘记 #include< type_traits> ; for
std :: enable_if
和 std :: is_same
。
In my project i have functions with different number of input parameters with different types. Since these functions are parts of libraries, I cannot change their definitions or bodies.
void methodA(boolean p1, int p2, long p3){
... some unrelevant code here ...
}
void methodB(int p1, int p2, int p3, long p4){
... some unrelevant code here too ...
}
int methodC(long p4){
...
}
In my project i need to have a method, which would receive the address of one of these functions. Additionally it receives well-formed list of parameters (which fits the function in the first parameter). Then this method has to call the passed function with the passed parameters.
Here is what I have now: (i have simplified the code a bit to make my idea clear)
void intercaller(void* some_func_address, ...){
// VARARGS parameters extractor
va_list listPointer;
va_start( listPointer, some_func_address );
int p1 = va_arg( listPointer, int );
int p2 = va_arg( listPointer, int );
int p3 = va_arg( listPointer, int );
long p4 = va_arg( listPointer, long );
// TODO: THIS IS NOT GENERIC CALL , CANN ONLY CALL METHOD B
((void (*)( int , int , int , long )) some_func_address)( p1 , p2 , p3 , p4 );
va_end( listPointer );
}
My problem is the actual function call. The parameter list in the function call should be generic and should be able to include different number of parameters, sadly i dont know how to do that... I have tried passing varargs list like here:
((void (*)( va_list )) some_func_address)( listPointer);
but this messes up the parameters in the called function...
So my question is: is there a way to call a given function with given parameters in a generic manner? Maybe I need some sort of a typedeff or a wrapper function?
If you don't have std::invoke
yet, use variadic templates. To treat void
functions nicely, use SFINAE.
template<typename R, typename... Args>
auto call(R(*function)(Args...), Args... args) -> typename std::enable_if<!std::is_same<R, void>::value, R>::type {
return function(args...);
}
template<typename... Args>
void call(void (*function)(Args...), Args... args) {
function(args...);
}
Example:
void a() {
std::cout << 'a';
}
void b(int a) {
std::cout << "b:" << a;
}
int c(int a) {
return a;
}
int main() {
call(a);
call(b, 1);
std::cout << "c:" << call(c, 2);
}
Don't forget to #include <type_traits>
for std::enable_if
and std::is_same
.
这篇关于使用varargs参数的C ++泛型函数调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!