Reputation: 245
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
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