当涉及到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);
}
我以为我可能会做这样的事情......
void do_another_callbacks(std::string &s) {
for_each(m_acb.begin(), m_acb.end(), [&s](another_callback acb) {
acb(s);
});
}
但是这不能在MSVC2010中编译
答案 0 :(得分:5)
长例子的问题是my_func(_1,s)
就在那里被评估。您需要使用std::bind
(或boost::bind
)来调用范围中每个元素的函数。
您发布的替代代码确实有效,但由于do_callbacks
中的代码,整个示例无法编译:
void do_callbacks() {
for_each(m_cb.begin(), m_cb.end(), this);
}
this
的类型为B*
,不可调用。如果您定义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);
}