使用varargs参数的C ++泛型函数调用 [英] C++ generic function call with varargs parameter

查看:152
本文介绍了使用varargs参数的C ++泛型函数调用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的项目中,我有不同数量的输入参数和不同类型的函数。由于这些功能是图书馆的一部分,我无法改变他们的定义或机构。

  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.

Try it online!

这篇关于使用varargs参数的C ++泛型函数调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆