函数对象function object 以及boost::bind的一点了解
2012-05-18 12:18
423 查看
1 function object就是重载了operator()的类的对象, 像如下例子, 其实也许应该说是定义了operator()的类, 在thinking in c++中operator overloading都并没有提到operator()
可以看到 operator()(...),可以有任意个参数, 和任意类型返回值
2. STL中的一个头文件<functional> http://www.cplusplus.com/reference/std/functional/
标准库在这个头文件中提供了两个base class : unary_function和binary_function, 这两个class 模板只是把template参数的名字, 也就是类型名, 统一化而以, 这个头文件中定义了很多operation class,就是定义了operation()的类, 我们可以把它用在很多STL algorithm中, 这些operation类都从两个base class之一派生, 从两个base class之一派生就是为了让function object具有可适配的特性, 就是可以 bind什么的, boost::bind用这样一个名称集合了STL的functional提供的所有可让普通函数, 成员函数变为function object中的operator()来调的方法
列出<functional>中greater的定义, 可以看看模板类又带继承是怎么写的
3. boost::thread对像在构建时要传入一个 object of callable type that can be invoked with no parameters to the constructor(callable就是要定义operator()), 也就是有默认构造函数的函数对象, 以下是我写的一个例 子
运行结果比较长,我就不列出来了,仔细看看这个程序做了什么事,就是在main中启动了两个线程,线程执行的函数分别是类Wy的两个operator()成员。
上面的程序编译的时候要链接libboost_thread,在我本地是这么做的:g++ -o operator_call operator_call.cpp -lboost_thread -L/usr/local/lib
第1行被注掉了,但sleep(2)依然可以被调用,休两秒,不明白是为什么,boost::thread中也有sleep的函数,只是参数也是库中定义的类型; 25,26行构造了两个thread对象,代表两个线程,传进去的参数都是function object,注意26行boost::bind是怎么使用function object的,指明了返回值,对象本身,和依次调用的参数,这个参见boost::bind文档; 在27行thread1.join()等待thread1退出, 由于thread2会先于thread1退出,所以程序在28行打印"thread1 end"时thread2已经退出了
引发这个思考的是在talk工程的main函数中,分出了一个线程运去行TalkServer.start(), 主线程是运行了一个Ice adapter,里面添加了相应的objectPtr, 运行了具本的ice服务, 在启动这个线程是这么做的
talkServer是之前定义的一个引用,这引出下面一般性的讨论
4, use boost::bind with pointers to members http://www.boost.org/doc/libs/1_46_1/libs/bind/bind.html#with_function_objects
这个地方我也没有特别完全理解,现在只列出一基本的知道的, bind(&X::f, args)相当于 bind<R>(mem_fn(&X::f), args), 而 mem_fn是boost对于std::mem_fun和std::mem_fun_ref(这义于std的<functional>)的一般性扩展, mem_fun构建出function object,并且其args第一个参数要是成员所属的那个对象的pointer, reference, 或smart_ptr(持有这个类对象), 像上面我用的就是talkServer的pointer(但我在talk中把这里的pointer改为reference, talkServer本身就是个reference,编译出错)
#include <iostream> #include <string> using namespace std; class Wy { public : string operator()(string msg, int a, int b){ cout << "msg = " << msg << endl; cout << "a = " << a << " b = " << b << endl; return msg; } }; int main(){ Wy wy; string msg = wy("test", 2, 3); cout << "in main msg = " << msg << endl; return 0; }
可以看到 operator()(...),可以有任意个参数, 和任意类型返回值
2. STL中的一个头文件<functional> http://www.cplusplus.com/reference/std/functional/
标准库在这个头文件中提供了两个base class : unary_function和binary_function, 这两个class 模板只是把template参数的名字, 也就是类型名, 统一化而以, 这个头文件中定义了很多operation class,就是定义了operation()的类, 我们可以把它用在很多STL algorithm中, 这些operation类都从两个base class之一派生, 从两个base class之一派生就是为了让function object具有可适配的特性, 就是可以 bind什么的, boost::bind用这样一个名称集合了STL的functional提供的所有可让普通函数, 成员函数变为function object中的operator()来调的方法
template<class Arg, class Result> struct unary_function{ typedef Arg argument_type; typedef Result result_type; }; template<class Arg1, class Arg2, class Result> struct binary_function{ typedef Arg1 first_argument_type; typedef Arg2 second_argument_type; typedef Result result_type; };
列出<functional>中greater的定义, 可以看看模板类又带继承是怎么写的
template<class T> struct greater : public binary_function<T, T, bool>{ bool operator(const T& a, const T&b) const{ return a>b; } } ;
3. boost::thread对像在构建时要传入一个 object of callable type that can be invoked with no parameters to the constructor(callable就是要定义operator()), 也就是有默认构造函数的函数对象, 以下是我写的一个例 子
//#include <unistd.h> #include <iostream> #include <string> #include <boost/thread.hpp> using namespace std; class Wy{ public : string operator()(string msg, int a, int b){ for (int i=0; i<15; i++){ cout << "thread2 : msg = " << msg << endl; cout << "a = " << a << " b = " << b << endl; sleep(1); } return msg; } void operator()(){ for (int i=0; i<10; i++){ cout << "thread1: msg in operator() " << endl; sleep(2); } } }; int main(){ Wy wy; boost::thread thread1(wy); boost::thread thread2(boost::bind<string>(wy, "test2", 5, 6)); thread1.join(); cout << "thread1 end " << endl; thread2.join(); return 0; }
运行结果比较长,我就不列出来了,仔细看看这个程序做了什么事,就是在main中启动了两个线程,线程执行的函数分别是类Wy的两个operator()成员。
上面的程序编译的时候要链接libboost_thread,在我本地是这么做的:g++ -o operator_call operator_call.cpp -lboost_thread -L/usr/local/lib
第1行被注掉了,但sleep(2)依然可以被调用,休两秒,不明白是为什么,boost::thread中也有sleep的函数,只是参数也是库中定义的类型; 25,26行构造了两个thread对象,代表两个线程,传进去的参数都是function object,注意26行boost::bind是怎么使用function object的,指明了返回值,对象本身,和依次调用的参数,这个参见boost::bind文档; 在27行thread1.join()等待thread1退出, 由于thread2会先于thread1退出,所以程序在28行打印"thread1 end"时thread2已经退出了
引发这个思考的是在talk工程的main函数中,分出了一个线程运去行TalkServer.start(), 主线程是运行了一个Ice adapter,里面添加了相应的objectPtr, 运行了具本的ice服务, 在启动这个线程是这么做的
boost::thread thread(bind(&TalkServer::start, &talkServer));
talkServer是之前定义的一个引用,这引出下面一般性的讨论
4, use boost::bind with pointers to members http://www.boost.org/doc/libs/1_46_1/libs/bind/bind.html#with_function_objects
这个地方我也没有特别完全理解,现在只列出一基本的知道的, bind(&X::f, args)相当于 bind<R>(mem_fn(&X::f), args), 而 mem_fn是boost对于std::mem_fun和std::mem_fun_ref(这义于std的<functional>)的一般性扩展, mem_fun构建出function object,并且其args第一个参数要是成员所属的那个对象的pointer, reference, 或smart_ptr(持有这个类对象), 像上面我用的就是talkServer的pointer(但我在talk中把这里的pointer改为reference, talkServer本身就是个reference,编译出错)
相关文章推荐
- Boost关于bind的使用以及函数对象和传递参数的问题
- boost::bind绑定成员函数时,第一个参数传递对象的特殊情况
- 【C++】boost::bind和函数对象一起使用实现便捷的异步编程
- boost::bind会返回一个函数对象,它内部保存了数据的拷贝
- Boost函数对象 boost.bind boost.function Boost.Ref Boost.Lambda
- Boost.Bind用法详解(一) 2008-05-09 15:50:50| 分类: C++ |字号 订阅 Boost.Bind 为函数和函数对象提供了一致的语法,对于值语义和指针语义也一样。
- jQuery 核心函数以及jQuery对象
- 函数对象 function object
- Boost学习------函数对象
- [boost-3] 函数对象
- c++ static的作用,以及static对象在类和函数中区别
- 临时函数对象作为函数参数 以及 类模板编程的文件组织
- Mootools中使用bind给函数绑定对象
- 关于new、Create、对象以及窗口的一点问题
- C++ 11 - STL - 函数对象(Function Object) (中)
- js中函数对象的方法,原型方法apply、call、bind、toString、toLocaleString、valueOf
- 从C到C++看面相对象(深入了解C++的成员函数)
- jQuery 核心函数以及jQuery对象
- C++函数对象 (Function object)
- find(),find_if(),以及巧妙的函数对象,函数适配器