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

标签 c++ lambda callback foreach

我在 c++0x、lambda 等方面还很新手,所以我希望你们能帮我解决这个小问题。

我想将一堆回调存储在一个 vector 中,然后在合适的时候使用 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);
}

我想我也许可以做这样的事情......

void do_another_callbacks(std::string &s) {

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

但在 MSVC2010 中无法编译

最佳答案

这个长示例的问题在于 my_func(_1,s) 会立即被求值。您需要使用 std::bind(或 boost::bind)在范围内的每个元素上调用该函数。

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

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

thisB* 类型,不可调用。如果您定义一个 result_type typedef 来匹配 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);
}

关于C++ for_each 调用回调函数 vector 并向每个回调函数传递一个参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3257896/

相关文章:

javascript - 在不使用 Promises 的情况下按顺序执行回调

c++ - 禁止跨编译单元包含不兼容的 header

c++ - 混淆hashmap和hashtable的区别

c++ - 在 C++ 中添加两个 lambda 函数

c# - => 运算符的作用是什么?

android - 在回调中使用正确的上下文

C++ Primer Plus this 指针示例

c++ - 从 MSVC 输出生成 Makefile 依赖项

c# - 规范模式 - 使用 lambdas 创建复合规范 (C#)

javascript - 使用 async.map 保留结果的顺序