2010-07-15 98 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

相關問題