如何使用std :: bind没有静态成员函数?

时间:2016-05-07 12:42:39

标签: c++ c++11

我试图通过实现一些众所周知的设计模式来学习一些基本的c ++ 11概念。目前我在尝试用C ++实现新的Angular2 EventEmitter模式时遇到了Callables。 所以这里是代码,如果评论保持一切正常:

class Controller {

public:

Controller() {
    const pattern::EventEmitter<SwitchEvent> listner;
    listner.subscribe([this](const SwitchEvent& event) {
        if(event.get_state()) {
            this->_count++;
            std::cout << "count: " << this->_count << std::endl;
        }
    });
    //listner.subscribe(std::bind(&Controller::track, this));
}

private:

int _count = 0;

void track(const SwitchEvent& event) {
    if(!event.get_state()) {
        this->_count++;
        std::cout << "count: " << this->_count << std::endl;
    }
}

};

并且输出符合预期:

$ g++ -std=c++11 -Wall test.cc
$ ./a.out 
count: 1 

但是当我删除评论时,我收到错误:

test.cc: In constructor ‘Controller::Controller()’:
test.cc:50:62: error: no matching function for call to ‘pattern::EventEmitter<SwitchEvent>::subscribe(std::_Bind_helper<false, void (Controller::*)(const SwitchEvent&), Controller*>::type) const’
     listner.subscribe(std::bind(&Controller::track, this));
                                                          ^
test.cc:50:62: note: candidate is:
In file included from test.cc:1:0:
EventEmitter.hh:16:6: note: void pattern::EventEmitter<T>::subscribe(const std::function<void(const T&)>&) const [with T = SwitchEvent]
void subscribe(const std::function<void(const T&)>& listener) const {
  ^
EventEmitter.hh:16:6: note:   no known conversion for argument 1 from ‘std::_Bind_helper<false, void (Controller::*)(const SwitchEvent&), Controller*>::type {aka std::_Bind<std::_Mem_fn<void (Controller::*)(const SwitchEvent&)>(Controller*)>}’ to ‘const std::function<void(const SwitchEvent&)>&’

3 个答案:

答案 0 :(得分:4)

您需要提供bind占位符,以便它知道它需要一个参数:

listner.subscribe(std::bind(&Controller::track, this, std::placeholders::_1));

否则,它将为您提供一个nullary函数对象,您无法使用它来构造std::function

答案 1 :(得分:1)

你需要通过第二个&#34; track()的参数,即事件。绑定到this的第一个参数,但缺少第二个参数。所以你需要这样的东西:

using namespace std::placeholders;
listner.subscribe(std::bind(&Controller::track, this, _1));

答案 2 :(得分:1)

由于您将其标记为C ++ 11,因此您最好使用lambda:

listner.subscribe([this](const SwitchEvent& event) {
  if(!event.get_state()) {
    _count++;
    std::cout << "count: " << _count << std::endl;
}});

否则,请使用占位符作为track参数event

listner.subscribe(std::bind(&Controller::track, this, std::placeholders::_1));