我试图理解std :: bind如何与成员函数指针一起工作。所以这个例子对我来说很清楚。
#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替换为5并且函数被调用,因为我期望它。
看另一个例子,它结合了一个成员函数和来自Effective C ++的std :: function。
#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;
}
我的主要困惑在于上面的占位符_1。有人可以帮我解决这个问题吗?在上面的例子中,_1是调用函数时传递给它的值,但我不明白在创建对象时如何解决这个问题。
感谢。
答案 0 :(得分:1)
_1 ... _N是占位符(因为它们位于std ::占位符中非常明显。 你通过使用它们来做的是告诉哪个参数用于哪个函数参数。
SomeClasss obj;
auto f1 = std::bind(&SomeClass::SomeFunction, &obj, _1, _2);
这意味着当调用SomeClass :: SomeFunction时,f1的第一个参数将用作第一个参数,而f1的第二个参数将用作第二个参数。 你也可以做像
这样的事情SomeClass obj;
auto f2 = std::bind(&SomeClass::SomeFunction, &obj, _2, _1);
现在f2的第一个参数是第二个参数,第二个参数是调用SomeClass :: SomeFunction时的第一个参数。
那你用
做什么EvilBadGuy ebg3(std::bind(&GameLevel::health, std::cref(currentLevel),_1))
是在对象currentLevel上使用其healthFunc beeing GameLevel :: health来构造和EvilBadGuy对象。 healthFunc的第一个参数将是传递给GameLevel :: health的第一个参数。