std :: bindがメンバー関数ポインタとどのように機能するかを理解しようとしています。だから、この例は私には明らかです。C++バインド関数のポインタを使用して
#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に置き換えられ、関数は期待通りに呼び出されます。
他の例を見てみましょう。この例では、メンバー関数とStd :: Functionを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;
}
私の主な混乱の原因は、上記のプレースホルダ_1です。何人かは私のためにこれを壊してもいいですか?上記の例では、関数が呼び出されたときに_1が渡された値でしたが、オブジェクトの作成時にこれがどのように解決されるかはわかりません。
ありがとうございました。
あなたはbind_を理解したいと思っていますが、一般的には、lambdaを使ってメンバー関数をラップすることをお勧めします。 –
'F(param)'は 'F(param)'を呼び出す関数オブジェクト( 'F')を生成します: currentLevel.health(param) 'です。このオブジェクトはさらに 'std :: function'でラップされ、渡され、最後に呼び出されます。 –