Search code examples
c++c++11functional-programmingstd-functionstdbind

C++ functional: bind classes method through pointer


I tried to bind a classes method from another class which is storing the first one's pointer, but it always gives me different value. What am I doing wrong?

If I pass class A by value (and of course modify class B to store by value) it's working.

#include <iostream>
#include <functional>

using namespace std;

class A {
public:
    A(double a, double b) : a(a), b(b) {}
    double mul(void) {return a*b;}

private:
    double a;
    double b;
};

class B {
typedef std::function<double(void)> function;

public:
    B(A* ap) : ap(ap) {}

    function a_mul = bind(&A::mul, ap);

private:
    A* ap;
};

int main() {
  A* a = new A(2,3);
  B b(a);

  cout << b.a_mul() << endl;

  return 0;
}

Solution

  • You're using a non-static data member initializer to initialize a_mul. The initial value depends on the value of ap. However, the definition of ap follows that of a_mul. This means that a_mul will be initialized prior to the initialization of ap in the constructor. At the time initilization occurs, ap has an indeterminate value, and thus your code has undefined behavior.

    One way to fix this is changing the order of definition of the member variables:

    class B {
    typedef std::function<double(void)> function;
    
    public:
        B(A* ap) : ap(ap) {}
    
        A* ap;
        function a_mul = bind(&A::mul, ap);
    };
    

    But a better fix would be reorder the data members, and initialize a_mul in the constructor's initializer list.

    class B {
    
    typedef std::function<double(void)> function;
    
    private:
        A* ap;
    
    public:
        B(A* ap) : ap(ap), a_mul(bind(&A::mul, ap)) {}
    
        function a_mul;
    };