搞乱std :: function和成员函数指针:(

时间:2018-04-12 17:19:40

标签: c++ c++11 std-function

所以,我以为我已经理解了成员函数指针和std :: fuction,但遗憾的是情况并非如此。

我有以下代码 - 它是状态机的一些早期部分,但我正在努力。让我粘贴代码:

#include <iostream>
#include <functional>
#include <map>

//forward decls
class state_t;

enum event_t
{
    ev_start = 0,
    ev_middle,
    ev_end
};

struct transition_t
{

    //std::function<bool()> guard_function();
    std::function<bool()> guard_function;
    state_t *p_next_state;
};

class state_t
{
public:
    std::map<event_t, transition_t> transitions;

    bool some_guard()
    {
        std::cout << "check the guard condition - all is well" << std::endl;
        return true;
    }
};

int main()
{
    std::cout << "Hello World!" << std::endl;

    state_t s1;
    state_t s2;

    // Setup transitions

    s1.transitions[event_t::ev_start]  = transition_t{s1::some_guard, &s2};
    s1.transitions[event_t::ev_middle] = transition_t{nullptr, &s2}; // no guard

    event_t test_event = event_t::ev_start;

    auto trans = s1.transitions.find(event_t::ev_start);
    if (trans != s1.transitions.end())
    {
        // change state - TBD
        std::cout << "changingn state" << std::endl;
    }

    return 0;
}

好的,所以:

  • event_t只是一些枚举
  • transition_t意味着包含一个指向某个保护函数的指针,该函数返回一个bool和一个指向下一个状态的指针。
  • state_t有一个事件和转换的映射,并包含一些可以存储在transition_t中的保护函数。

所以在main()中我试图构建一些状态......

s1.transitions[event_t::ev_start]  = transition_t{s1::some_guard, &s2};   // <--- this line fails
s1.transitions[event_t::ev_middle] = transition_t{nullptr, &s2}; // <--- this line works (not so surprised)

但我无法弄清楚如何对此进行排序。我过去用lambdas和模板做过这个...但我真的想给std :: function一个去看它是否更好/更容易......

任何指针/指南在这里做什么都会受到欢迎,即使它使用lambdas :),但我更喜欢让std :: function工作

1 个答案:

答案 0 :(得分:3)

这应该有效,因为你需要将成员函数绑定到它是实例。

感谢下面的@Barry评论,使用lambda解决方案比使用bind

更好
s1.transitions[event_t::ev_start] = transition_t{ [&s1] { return s1.some_guard(); }, &s1 };
s1.transitions[event_t::ev_start] = transition_t{ std::bind(&state_t::some_guard, &s1), &s1 };

我找到了绑定vs lambda的一些性能线程。 std::bind vs lambda performance

lambda函数看起来也更容易阅读。