boost::signals2::signal 主要用来发射一个信号,然后由预先connect的函数指针接收这样的信号做处理.
最简单的例子就是connect一个裸露的function pointer. 如果需要connect的是一个实例对象内部的函数,则需要用到boost::bind, 如果需要signal自动判断这个实例对象是否存在,则需要用到boost::shared_ptr 和 track. 以下是一个简单的例子
#include <iostream>
#include <boost/signals2.hpp>
#include <boost/signals2/slot.hpp>
using namespace std;
class HelloWorld
{
public:
HelloWorld() { a = 10; }
void func0() { cout << "a:" << &a << endl;}
void func1(int t) { cout << "hello world! " << t << " " << a << endl; }
int a;
};
boost::signals2::signal<void()> sig0; // void 是返回值,就是定义一个connect的函数形式
boost::signals2::signal<void(int)> sig1;
HelloWorld hello_g;
void test_0()
{
boost::shared_ptr<HelloWorld> hello_ptr(new HelloWorld());
sig0.connect(boost::signals2::signal<void()>::slot_type(&HelloWorld::func0, hello_ptr.get()).track(hello_ptr)); // 使用track自动判断hello_ptr是否存在,自动bind
//sig0.connect(boost::bind(&HelloWorld::func0, hello_ptr.get(), _1).track(hello_ptr));
sig0();
sig1.connect(boost::bind(&HelloWorld::func1, &hello_g, _1));
}
int main(int argc, char *argv[])
{
test_0();
sig0(); // 由于hell_ptr已经被destroy,这里信号无效
sig1(100);
return 0;
}
到这里发现bind很有意思,那么bind的用法是什么,在什么地方比较好用呢?
http://www.informit.com/articles/article.aspx?p=412354
与lambda表达式类似,感觉主要为stl, algorithm中的一些函数服务,这些函数需要你往里面传一个function or function object, 而这些时候你往往需要自己手动再去写一个只有这里会用到的function or function object. 这样既不简洁,又容易与其他function or function object混淆起来. 这时候,若可以通过已有的function构造这样一个function,用bind就比较清楚和方便.
std::sort( first, last, bind( &X::name, _1 ) < bind( &X::name, _2 ) ); // sort by name boost的bind能够overload operator
<span style="font-family: monospace;font-size:14px;">std::remove_if( first, last, !bind( &X::visible, _1 ) ); // remove invisible objects</span>
现在c++11也有std::bind但是不支持overload operator
Ok, 那么如果是用lambda表达式该怎么写呢?
参考:http://en.cppreference.com/w/cpp/language/lambda
最简单的是:
/× [ capture-list ] ( params ) -> ret { body }
其中capture-list是在lambda中直接使用的变量, params传值
×/
for_each(vec.begin(), vec.end(), [](X x){ cout << x.value << " "; });