C++ 使用指针绑定成员函数

C++ bind member functions using pointers

我想了解 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 是调用函数时传递给它的值,但我无法理解创建对象时如何解析它。

谢谢。

_1 ... _N 是占位符(这很明显,因为它们在 std::placeholders 中。 你通过使用它们所做的是告诉哪个参数用于哪个函数参数。

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);

现在调用SomeClass::SomeFunction时f2的第一个参数是第二个参数,第二个参数是第一个参数

那么你用

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

是构造 EvilBadGuy 对象,其 healthFunc 在对象 currentLevel 上 GameLevel::health。 healthFunc 的第一个参数将是传递给 GameLevel::health.

的第一个参数