C++ for_each调用回调函数的向量并向每个函数传递一个参数

sha*_*haz 3 c++ foreach lambda callback

当涉及到c ++ 0x,lambda等时,我是相当绿色的,所以我希望你们可以帮助我解决这个小问题.

我想在向量中存储一堆回调,然后在时机成熟时使用for_each来调用它们.我希望回调函数能够接受参数.这是我现在的代码.问题在于void B :: do_another_callbacks(std :: string&)

#include <boost/bind.hpp>
#include <boost/function.hpp>
#include <vector>
#include <iostream>
#include <algorithm>



class A {
public:
    void print(std::string &s) {
        std::cout << s.c_str() << std::endl;
    }
};

typedef boost::function<void(std::string&)> another_callback;
typedef boost::function<void()> callback;

typedef std::vector<callback> callback_vector;
typedef std::vector<another_callback> another_callback_vector;

class B {
public:
    void add_callback(callback cb) {
        m_cb.push_back(cb);
    }

    void add_another_callback(another_callback acb) {
        m_acb.push_back(acb);
    }

    void do_callbacks() {
        for_each(m_cb.begin(), m_cb.end(), this);
    }

    void do_another_callbacks(std::string &s) {
        std::tr1::function<void(another_callback , std::string &)> my_func = [] (another_callback acb, std::string &s) { acb(s); }
        for_each(m_acb.begin(), m_acb.end(), my_func(_1, s));
    }

    void operator() (callback cb) { cb(); }

private:
    callback_vector m_cb;
    another_callback_vector m_acb;
};

void main() {
    A a;
    B b;
    std::string s("message");
    std::string q("question");
    b.add_callback(boost::bind(&A::print, &a, s));
    b.add_callback(boost::bind(&A::print, &a, q));
    b.add_another_callback(boost::bind(&A::print, &a, _1));
    b.do_callbacks();
    b.do_another_callbacks(s);
    b.do_another_callbacks(q);
}
Run Code Online (Sandbox Code Playgroud)

我以为我可能会做这样的事......

void do_another_callbacks(std::string &s) {

    for_each(m_acb.begin(), m_acb.end(), [&s](another_callback acb) {
        acb(s);
    });
}
Run Code Online (Sandbox Code Playgroud)

但这不能在MSVC2010中编译

Ant*_*ams 5

长例子的问题是在my_func(_1,s)那里然后进行评估.您需要使用std::bind(或boost::bind)在范围中的每个元素上调用该函数.

您发布的替代代码确实有效,但由于以下代码,整个示例无法编译do_callbacks:

void do_callbacks() {
    for_each(m_cb.begin(), m_cb.end(), this);
}
Run Code Online (Sandbox Code Playgroud)

this是类型B*,不可调用.如果您定义一个result_typetypedef以匹配返回类型,operator()那么您可以使用std::ref(*this).以下代码在MSVC10下编译并运行:

#include <functional>
#include <vector>
#include <iostream>
#include <algorithm>



class A {
public:
    void print(std::string &s) {
        std::cout << s.c_str() << std::endl;
    }
};

typedef std::function<void(std::string&)> another_callback;
typedef std::function<void()> callback;

typedef std::vector<callback> callback_vector;
typedef std::vector<another_callback> another_callback_vector;

class B {
public:
    void add_callback(callback cb) {
        m_cb.push_back(cb);
    }

    void add_another_callback(another_callback acb) {
        m_acb.push_back(acb);
    }

    void do_callbacks() {
        std::for_each(m_cb.begin(), m_cb.end(), std::ref(*this));
    }

    void do_another_callbacks(std::string &s) {

        std::for_each(m_acb.begin(), m_acb.end(), [&s](another_callback acb) {
                acb(s);
            });
    }

    typedef void result_type;
    void operator() (callback cb) { cb(); }

private:
    callback_vector m_cb;
    another_callback_vector m_acb;
};

int main() {
    A a;
    B b;
    std::string s("message");
    std::string q("question");
    b.add_callback(std::bind(&A::print, &a, s));
    b.add_callback(std::bind(&A::print, &a, q));
    b.add_another_callback(std::bind(&A::print, &a, std::placeholders::_1));
    b.do_callbacks();
    b.do_another_callbacks(s);
    b.do_another_callbacks(q);
}
Run Code Online (Sandbox Code Playgroud)