2010-07-15 141 views
3

当我提到C++ 0x,lambda等时,我相当绿色,所以我希望你们可以帮我解决这个小问题。C++ for_each调用一个回调函数的向量并传递每个参数

我想在矢量中存储一堆回调,然后在时间正确时使用for_each来调用它们。我希望回调函数能够接受参数。这是我的代码现在。麻烦的是无效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

+0

下面的代码应该可以工作*原则上* - 您得到什么错误? – Dario 2010-07-15 16:59:39

回答

5

长示例的问题是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); 
} 
+0

太棒了!非常感谢你的帮助安东尼。 – shaz 2010-07-16 14:42:58

相关问题