具有变量计数和类型参数的函数指针?

Posted

技术标签:

【中文标题】具有变量计数和类型参数的函数指针?【英文标题】:Function-pointer with variable count and type parameter? 【发布时间】:2020-07-20 17:44:21 【问题描述】:

在 C++ 中,我需要将一些变量传递给函数,并且我希望该函数使用我的参数回调我的函数指针:

// Example program
#include <iostream>
#include <string>

using namespace std;

typedef void(*callback)(int,int);

void otherFunction(string query, callback c, ??) 
    cout << "otherFunction is processing data" << endl;
    c(??, queryResult);


void callbackAfterOtherFunction(int queryId, int result) 
    cout << "Calculation finished: value=" << value << ", value2=" << value2 << ", result=" << result << endl;


void doSomething(string query, int queryId) 
  otherFunction(query, callbackAfterOtherFunction, queryId);       


int main()

  doSomething("QUERY", 1); 
  return 0;

这段代码有效,但我觉得很难看,因为我必须为我的回调函数定义参数列表int,int,int

在 C++ 中有什么方法可以用来简化这个吗?即:otherFunction 只会得到一个函数指针和一些参数,它会使用提供的参数+其单个 int 计算结果调用该函数。

注意:callbackAfterOtherFunction 是线程安全的,因为otherFunction 可能会从不同的线程中回调它。

示例: 考虑一个 DBManager 类,它可以以异步方式从 DB 中查询数据,因此它定义了接受查询的 otherFunction(在本例中为 query),以及一个函数指针,一旦查询到数据,它将回调。但是我作为 DBManager 是异步的,我可以在开始取回结果之前多次调用otherFunction。所以我想给otherFunction加参数来标记我的查询,这样当回调返回时,数据就可以区分了。

Berto99 的解决方案:

// Example program
#include <iostream>
#include <string>

using namespace std;

template<class Callback, class ...T>
void otherFunction(Callback c, T ...params) 
    cout << "otherFunction is processing data" << endl;
    int res=14;
    //c(params..., (params + ...));


void callbackAfterOtherFunction(int value, int value2, int result) 
    cout << "Calculation finished: value=" << value << ", value2=" << value2 << ", result=" << result << endl;


void doSomething(int value, int value2) 
    cout << "Processing values: Value=" << value << ", value2=" << value2 << endl;
    otherFunction(callbackAfterOtherFunction, value, value2);


int main()

    otherFunction(doSomething,2,3);
    return 0;

这里的预期结果是

计算完成:value=2, value2=3, result=14

【问题讨论】:

模板函子?问题未明确。显示您希望它如何工作的一些代码,其中callback 是一个不存在的占位符类型。尽可能具体地说明您希望它能够处理的场景。 看这篇文章。 ***.com/questions/11037393/… 看这篇文章。这可能会对您有所帮助。 ***.com/questions/11037393/… 【参考方案1】:

我建议使用variadic template 作为参数,使用template argument deduction 来避免声明函数的类型:

template<class Callback, class ...T>
void otherFunction(Callback c, T ...params) 
    cout << "otherFunction is processing data" << endl;
    c(params...); // if you want to have the last parameter to be the sum of all the parameters: c(params..., (params + ...));

整个代码应该是这样的:


template<class Callback, class ...T>
void otherFunction(Callback c, T ...params) 
    cout << "otherFunction is processing data" << endl;
    c(params...);


void callbackAfterOtherFunction(int value, int value2, int result) 
    cout << "Calculation finished: value=" << value << ", value2=" << value2 << ", result=" << result << endl;


void doSomething(int value, int value2) 
    cout << "Processing values: Value=" << value << ", value2=" << value2 << endl;
    //otherFunction(value, value2, callbackAfterOtherFunction);


int main()

    otherFunction(doSomething,2,3);
    return 0;

输出:

otherFunction is processing data
Processing values: Value=2, value2=3

编辑: 如果您需要参数的总和,感谢cdhowie,您可以使用前面的代码并像这样调用回调:

c(params..., (params + ...));

代码


template<class Callback, class ...T>
void otherFunction(Callback c, T ...params) 
    cout << "otherFunction is processing data" << endl;
    int res=14;
    c(params..., (params + ...));


void callbackAfterOtherFunction(int value, int value2, int result) 
    cout << "Calculation finished: value=" << value << ", value2=" << value2 << ", result=" << result << endl;


template<class ...T>
void doSomething(T ... els) 
    cout << "Processing values";
    otherFunction(callbackAfterOtherFunction, els...);


int main()

    doSomething(2,3);
    return 0;

【讨论】:

根据示例代码,调用应该是c(params..., 0 + ... + params); 假设加法。 OP 谈到有一个“int 结果”,但没有澄清操作。 @cdhowie 是的,我真的不明白他对 它的单一 int 计算结果的意思。 你的建议实际上是我迄今为止最好的解释 是的,这就是为什么我留下我对这个问题所做的评论。问题中没有足够的信息来明确说明 OP 正在寻找什么。 @cdhowie 实际上您提供的代码无法编译(不知道这是不是目的),但是,在底部编译的代码中添加了相同的逻辑 它无法与您的代码一起编译,因为您进行了不兼容的更改。尝试获取 OP 的代码并更改 only otherFunction().【参考方案2】:

最简单的解决方案是使用这样的模板:

// Example program
#include <iostream>
#include <string>

using namespace std;

template<typename C>
void otherFunction(int value, int value2, C c) 
    cout << "otherFunction is processing data" << endl;
    c(value, value2, value+value2);


void callbackAfterOtherFunction(int value, int value2, int result) 
    cout << "Calculation finished: value=" << value << ", value2=" << value2 << ", result=" << result << endl;


void doSomething(int value, int value2) 
  cout << "Processing values: Value=" << value << ", value2=" << value2 << endl;
  otherFunction(value, value2, callbackAfterOtherFunction);       


int main()

  doSomething(2,3); 
  return 0;

【讨论】:

【参考方案3】:

这将允许您计算任意数量的参数:

int a = 2;
int b = 3;
anotherFunction(acallbackAfterOtherFunction, doSomething,a,b,4,5,6);
using namespace std;

template<class Callback, typename T>
int otherFunction(Callback c, T one) 
    cout << "otherFunction is processing ONE data " << one << endl;
    return one;


template<class Callback, typename A, typename... T>
int otherFunction(Callback c, A one, T... params) 
    cout << "otherFunction is processing data" << endl;
    
    return c(otherFunction(c, one), otherFunction(c, params...));


template<typename P, class Callback, typename A, typename... T>
int anotherFunction(P p, Callback c, A one, T... params) 
    cout << "anotherFunction is processing data" << endl;
    int i = c(otherFunction(c, one), otherFunction(c, params...));
    p (i);
    return i;


void callbackAfterOtherFunction(int value, int value2, int result) 
    cout << "Calculation finished: value=" << value << ", value2=" << value2 << ", result=" << result << endl;


void acallbackAfterOtherFunction(int result) 
    cout << "Calculation finished: result=" << result << endl;


int doSomething(int value, int value2) 
    cout << "Processing values: Value=" << value << ", value2=" << value2 << endl;
    return value + value2;
    //otherFunction(value, value2, callbackAfterOtherFunction);


int main()

    int a = 2;
    int b = 3;
    int r = anotherFunction(acallbackAfterOtherFunction, doSomething,a,b,4,5,6);
    cout << "R: " << r << endl;
    return 0;


【讨论】:

以上是关于具有变量计数和类型参数的函数指针?的主要内容,如果未能解决你的问题,请参考以下文章

C语言的数据类型——指针

映射到具有不同数量参数和不同数据类型的函数指针

指针函数和函数指针

类函数指针(不涵盖:返回类函数指针)

C语言特殊函数的应用

结构体指针与结构体变量用作函数参数时有啥区别,在用法上