Bobo
Bobo

Reputation: 245

C++ bind member functions using pointers

I am trying to understand how std::bind works with member function pointers. So this example is pretty clear to me.

#include<iostream>
#include<functional>

using namespace std::placeholders;

struct Foo 
{
    void print_sum(int n1, int n2)
    {
        std::cout << n1+n2 << '\n';
    }
};


int main()
{    
    Foo foo;
    auto f3 = std::bind(&Foo::print_sum, &foo, 95, _1);
    f3(5); //prints 100
    return 0;
}

_1 is replaced with 5 and the function is called as i expect it to.

Looking at another example , which combines binding a member function along with std::function from Effective C++.

#include<iostream>
#include<functional>

using namespace std::placeholders;

class GameCharacter; // forward declaration

int defaultHealthCalc(const GameCharacter& gc) 
{
    std::cout<<"Calling default function";
    return 10;
}

class GameCharacter
{ 
public:
    typedef std::function<int (const GameCharacter&)> HealthCalcFunc; 
    explicit GameCharacter(HealthCalcFunc hcf = defaultHealthCalc)  :healthFunc(hcf){} // constructor
    void setHealthFunction(HealthCalcFunc hcf)
    { 
        healthFunc = hcf;
    }

    int healthValue() const 
    { 
        return healthFunc(*this);
    }
private:
    HealthCalcFunc healthFunc; // pointer to function
};

class EvilBadGuy : public GameCharacter{
public:
    explicit EvilBadGuy(HealthCalcFunc hcf = defaultHealthCalc) : GameCharacter(hcf) {} // constructor
};

class GameLevel{
public:
    GameLevel(int l = 1) : level(l){}
    int health(const GameCharacter& gc) const   
    {
        std::cout<<"Calling gamelevel health"<<std::endl;
        return level * 10000;
    }
    void setLevel(int l) {
        level = l;
    }
private:
    int level;
};

int main()
{    
    GameLevel currentLevel; // default construct 
    EvilBadGuy ebg3(std::bind(&GameLevel::health, std::cref(currentLevel),_1)); // what is _1 here ?
    std::cout << ebg3.healthValue() << std::endl;

    return 0;
}

My main source of confusion lies with the place holder _1 above. Can some one please break this down for me? In the above example , _1 was the value passed to it when the function was called , but i cant understand how this is resolved when the object is created.

Thanks.

Upvotes: 1

Views: 2388

Answers (1)

GSIO01
GSIO01

Reputation: 501

_1 ... _N are placeholders (which is pretty obvious as they are in std::placeholders. What you do by using them is to tell which argument to use for which function parameter.

SomeClasss obj;
auto f1 = std::bind(&SomeClass::SomeFunction, &obj, _1, _2);

This means the first argument of f1 will be used as first parameter when SomeClass::SomeFunction is called and the second argument of f1 will be used as second paramater. You could also do somthing like

SomeClass obj;
auto f2 = std::bind(&SomeClass::SomeFunction, &obj, _2, _1);

Now the first argument of f2 is the second paramter and the second argument is the first parameter when SomeClass::SomeFunction is called.

So what you do with

EvilBadGuy ebg3(std::bind(&GameLevel::health, std::cref(currentLevel),_1))

is to contruct and EvilBadGuy object with its healthFunc beeing GameLevel::health on the object currentLevel. The first argument of healthFunc will be the first parameter passed to the GameLevel::health.

Upvotes: 1

Related Questions