How to save a callback function with it's paramater and call it later

Hi everyone.
I have a problem with my project.
I have a function (name Callback), with take some parameter( name Arg). I want to create it before, pass it to other class ( class B). And in class B, call the Callback function with Arg paramater.
It's something like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class A
{
   void A::doSomething(int a, bool b){//dosomething};
   void A::setCallback(B b) {//I don't know how to do this};
}

class B
{
   void B::doSomething()
  {
     if(true)
     {
        //do A callback with it's paramater
     }
  }
}

void main()
{
   A a, B b;
   a.setCallback(b);
   b.doSomething();
}


How can i do this? And what happen with I want B can get more type of callback function, which mean I don't know the type of Callback's paramater?
Sorry for my bad English :(
Thanks for read.
It kind of depends on how the callback is defined -- which depends on what you plan to do with it.

The STL provides the std::bind() functor (in <functional>) to curry stuff like that.

You can find documentation and examples at http://en.cppreference.com/w/cpp/utility/functional/bind

Unfortunately, what you want to do is not beginner fare, so you've got a little reading and experimenting to do.

Good luck!

PS. Your English is fine.
Thank you.
I only have a little experience :)
I'm using the Function Pointer, like that:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
typedef void (*callback_function)();
class A
{
    void setCallback(callback_function callback);
    void doSomething()
    {
          //do something and call the callback
         callback();
    }
}

void callback()
{
    print("this is callback");
}

void main()
{
    A a;
   a.setCallback(callback);
   a.doSomething();
}
  


I have more than one callback, and want to store it in something like std::vector<callback_function>. Then in function doSomething, just check the vector and do all callback. The problem is I can't pass argument to my callback function, and if the callback have different params, it can't be store in one std::vector.
And another problem, the class function member can't be used as callback, right? I must use a static function to wrap it
An example of storing callbacks in a container, and calling them later:
http://www.cplusplus.com/forum/general/120687/#msg656918
Thank you, JLBorgers. It seem too hard but it is what I need. I will read and try it more and more.
And more question, what the problem with atoi function when run in debug mode and release mode. The code:
1
2
3
4
5
6
std::string test = "12";
char* temp = test.c_str();
char a = temp[0];
char b = temp[1];
int x = atoi(&a);
int y = atoi(&b);

In debug mode, it run corectly, and the result is x = 1, y = 2;
But in the release mode, it go out with x = 1, y = 12;
How can I solve it? I need to conver one by one part of std::string to int.
When you have a new problem, start a new thread with an appropriate subject.

You're unlucky enough to have this work at all. atoi expects a null terminated string. You're not giving it one. You're feeding it the address of two separate chars.

The following would work:
1
2
3
4
5
6
std::string test = "12";
const char* temp = test.c_str();
char a[2] = {temp[0], '\0'};
char b[2] = {temp[1], '\0'};
int x = atoi(a);
int y = atoi(b);


or:
1
2
3
std::string test = "12";
int x = test[0] - '0';
int y = test[1] - '0';

Thank you so much.
I will close this thread :)
@cire +1

@Dinh Hung: If you are not certain that every character in the string is a digit, you would want to check that first before subtracting '0'. Something like:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <iostream>
#include <string>
#include <cctype>

int main()
{
    const std::string test = "123456789";
    {
        for( char ch : test ) // for each character in the string
        {
            // if it is a digit, get the integer value of the digit
            // if it is not a digit, zero (a la atoi).
            const int x = std::isdigit(ch) ? ch - '0' : 0 ;
            std::cout << x << ' ' ;
        }
        std::cout << '\n' ;
    }
}




> It seem too hard but it is what I need. I will read and try it more and more.

It is not as hard as it appears at first sight if you take it one small step at a time.

Let us say, we have a function:
int function_one( int a, int b ) ;

We can easily write a function which takes no parameters, but calls function_one(10,5) and returns the result.
1
2
3
4
int bound_function()
{
    return function_one( 10, 5 ) ;
}


The implementation of bound_function() has these pieces of information:
a. the function to be called is function_one()
b. the first argument to be passed is the integer 10.
c. the second argument to be passed is the integer 5.
d. the result is an integer

std::bind() is a generalisation of this idea:
a. we have a function (callable object)
b. we also have one or more specific arguments to be passed to the function
We want to create a new callable object which will call the original function with the stored arguments.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#include <iostream>
#include <functional>

int function_one( int a, int b )
{
    const int result = a*a + b*b ;
    std::cout << "function_one( " << a << ", " << b << " ) => " << result << '\n' ;
    return result ;
}

double function_two( double a, double b, double c )
{
    const double result = a + b - c ;
    std::cout << "function_two( " << a << ", " << b << ", " << c << " ) => " << result << '\n' ;
    return result ;
}

int main()
{
    int x = 10 ;
    int y = 5 ;
    function_one( x, y ) ; // function_one( 10, 5 ) => 125

    // f1 is a callable object that can be called with no arguments
    // f1() would call function_one(10,5)
    const auto f1 = std::bind( function_one, 10, 5 ) ;
    f1() ; // function_one( 10, 5 ) => 125

    // f2() would call function_one(3,8)
    const auto f2 = std::bind( function_one, 3, 8 ) ;
    f2() ; // function_one( 3, 8 ) => 73

    // f3() would call function_two( 3.1, 28, 5.2 )
    const auto f3 = std::bind( function_two, 3.1, 28, 5.2 ) ;
    f3() ; // function_two( 3.1, 28, 5.2 ) => 25.9
}

http://coliru.stacked-crooked.com/a/b079d0543f52fd55

Once you have grasped this - you are comfortable with using std::bind() to bind arguments to functions, and then call the bound function with no arguments - make a post accordingly, and we cam move on to the next small step.
Topic archived. No new replies allowed.