0

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

3
  • Template functor? The problem is under-specified. Show some code of how you want it to work, where callback is a placeholder type that doesn't exist. Be as specific as you can about the scenarios you want it to be able to handle. Commented Jul 20, 2020 at 17:50
  • 1
    Look at this post. stackoverflow.com/questions/11037393/… Commented Jul 20, 2020 at 18:05
  • Look at this post. This may help you. stackoverflow.com/questions/11037393/… Commented Jul 20, 2020 at 18:07

3 Answers 3

1

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;
}
Sign up to request clarification or add additional context in comments.

14 Comments

Based on the sample code, the call should be c(params..., 0 + ... + params); assuming addition. OP talks about having an "int result" but doesn't clarify the operation.
@cdhowie yes well i don't really get what he meant with its single int calculation result. and what you are suggesting is actually the best interpretation that i had so far
Yeah, that's why I left the comment I did on the question. There's not enough information in the question to conclusively say what the OP is looking for.
@cdhowie actually the code you provided does not compile (don't know if that was the intent), however, added the same logic with code that compiles at the bottom
It doesn't compile with your code because you made incompatible changes. Try taking OP's code and changing only otherFunction().
|
1

The simplest solution is to use a template like this:

// 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;
}

Comments

1

This will allow you to calculate any number of parameters:

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;
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.