In C++ I need to pass some variables to a function, and I want that function to call back my function pointer with my parameters:
// 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;
}
This code works, but I find it ugly, because I have to define the parameter list int,int,int
for my callback function.
Is there any way in C++ which I can use to simplify this? I.e: otherFunction
would get only a functionpointer and some parameters, and it would call that function with provided parameters +its single int calculation result.
Note: callbackAfterOtherFunction
is thread-safe, as otherFunction
might call it back from a different thread.
Example:
Consider a DBManager class which can query data from the DB in asynchron way, so it defines otherFunction
which accepts the query (in this case query
), and a function pointer which it will call back once data has been queried. But I as DBManager is async I can call otherFunction
multiple times before starting to get back the results. Therefore I want to add parameters to otherFunction
to mark my queries, so when callbacks give them back, data can be distinguished.
Berto99's solution:
// 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;
}
Expected result here would be
Calculation finished: value=2, value2=3, result=14
I would suggest to use variadic template
for the parameters, and template argument deduction
to avoid declaring the type of the function:
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 + ...));
}
The whole code should look like this:
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;
}
Output:
otherFunction is processing data
Processing values: Value=2, value2=3
EDIT:
If you need the sum of the params, thanks to cdhowie, you can use the previous code and call the callback like this:
c(params..., (params + ...));
CODE
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;
}