繁体   English   中英

在 C++ 中将类型映射到该类型的函数

[英]Mapping a type to a function of that type in c++

假设我有一个角色可以同时具有 3 种状态中的 1 种状态(蹲伏、跳跃和行走)。 对于 3 个状态中的每一个,我都有一个 void() 类型的函数,它可以执行分配给它们的任何操作。 我还有一个存储不同状态的枚举和每个状态的数字。

class Player {
private:
   enum State {
       crouching = 0,
       walking= 1,
       jumping = 2
   } state;
}

我还有一张无序地图,用于将不同状态与其功能联系起来。

class Player {
private:
   std::unordered_map<int, void(Player::*)()> stateToFunc;

   void playerJump(){ /* code here */ };
   void playerCrouch(){ /* code here */ };
   void playerWalk(){ /* code here */ };

   Player() {
        // other stuff
        stateToFunc[0] = playerCrouch;
        stateToFunc[1] = playerWalk;
        stateToFunc[2] = playerJump;
}

我做到了,所以每次按下某个键时,状态变量都会更新。 我的目标是在每次更新时只调用函数stateToFunc[state]而不是使用 switch 语句手动检查。 它给了我以下错误:

 Error  C3867   'Player::gActivated': non-standard syntax; use '&' to create a pointer to member

如果我使用stateToFunc[0] = & playerCrouch; ,它给了我其他错误。 我能做些什么来实现这一目标?

您需要按照编译器告诉您的操作 - 使用&运算符获取指向成员方法的指针。 您还必须指定方法所属的类,例如:

class Player {
private:
   std::unordered_map<State, void(Player::*)()> stateToFunc;

   void playerJump(){ /* code here */ };
   void playerCrouch(){ /* code here */ };
   void playerWalk(){ /* code here */ };

   Player() {
        // other stuff
        stateToFunc[crouching] = &Player::playerCrouch;
        stateToFunc[walking] = &Player::playerWalk;
        stateToFunc[jumping] = &Player::playerJump;
    }

    ...
}

然后,要实际调用方法,可以使用->*运算符,如下所示:

void Player::doSomething()
{
    ...
    (this->*stateToFunc[state])();
    ...
}

或者,使用std::function代替std::bind()或 lambdas,例如:

class Player {
private:
   std::unordered_map<State, std::function<void()>> stateToFunc;

   void playerJump(){ /* code here */ };
   void playerCrouch(){ /* code here */ };
   void playerWalk(){ /* code here */ };

   Player() {
        // other stuff

        stateToFunc[crouching] = std::bind(&Player::playerCrouch, this);
        stateToFunc[walking] = std::bind(&Player::playerWalk, this);
        stateToFunc[jumping] = std::bind(&Player::playerJump, this);
        // or:
        stateToFunc[crouching] = [this](){ playerCrouch(); };
        stateToFunc[walking] = [this](){ playerWalk(); };
        stateToFunc[jumping] = [this](){ playerJump(); }
    }

    ...
}
void Player::doSomething()
{
    ...
    stateToFunc[state]();
    ...
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM