[boost-3] 函数对象
2017-09-24 23:10
344 查看
boost库学习;
函数对象,成为‘高阶函数’,可以呗传入到其他函数或者从其他函数返回的一类函数。
Boost.Bind可替换来自c++标准中的std::bind1st()和std::bind2dn()函数
Boost.Function则提供了一个用于封装函数指针的类。
Boost.Lambda引入了一种创建匿名函数的方法。
===
bind提供了一种机制,将这些函数与不限数量的参数一起使用,可以得到指定签名的函数。
//=====
#include <iostream>
#include <boost/thread/thread.hpp>
#include <boost/bind.hpp>
#include <vector>
#include <algorithm>
void hello(){
std::cout<<"hello world,I'm a thread from boost library"<<std::endl;
}
using namespace std;
void add(int i,int j){
std::cout<<i+j<<std::endl;
}
int main() {
std::vector<int> v;
v.push_back(1);
v.push_back(2);
v.push_back(3);
std::for_each(v.begin(),v.end(),boost::bind(add,10,_1));
return 0;
}
//======
_1被称为占位符(placeholder),定义于boost.bind。除了_1,boost.bind还定义了_2和_3。通过这些占位符,bind可以变为一元、二元或者三元的函数。对于_1,boost::bind变为一个一元函数(即只要求一个参数的函数)。因为for_each(只要求一个一元函数作为其第三个参数。)
ps:简单来说,_1指代的是vector中的元素值,作为add函数的第一个参数,10默认作为第二个参数。bind的第一个参数值是add函数名字。
======
如果用于boost::bind()的函数带有至少一个引用参数时,Boost.Ref就重要了。因为bind会复制它的参数,引用必须特殊处理。
<boost/ref.hpp>
std::for_each(v.begin(), v.end(), boost::bind(add, 10, _1, boost::ref(std::cout)));
=======
boost.function()的功能,为了封装函数指针;
位于boost/function.hpp中,
用法是:boost::function<int (const char*)>f= std::strlen;
定一个函数指针,表示此函数接受的参数类型为const char*,返回的参数类型为int。定义完成后,匹配此签名的函数都可以复制给这个指针。
因为f是一个函数指针,被赋值的函数可以通过重载的operator()()操作符来调用。
另外当f未被赋值,而被调用的,会发生boost::bad_function_call异常。
//======
#include <iostream>
#include <boost/thread/thread.hpp>
#include <boost/bind.hpp>
#include <vector>
#include <algorithm>
#include <boost/function.hpp>
#include <cstdlib>
#include <cstring>
struct world{
void hello(std::ostream &os){
os <<"helllo,world"<<std::endl;
}
};
int main() {
boost::function<int (const char*)> f = std::atoi;
std::cout<<f("1292")<<endl;
f = std::strlen;
std::cout<<f("1609")<<std::endl;
try {
boost::function<int (const char*)> f2;
f2("");
}catch (boost::bad_function_call &ex){
cout<<ex.what()<<endl;
}
boost::function<void (world*,std::ostream &)> f3 = &world::hello;
world w;
f3(&w,boost::ref(std::cout));
return 0;
}
//======
=====
参考:http://zh.highscore.de/cpp/boost/functionobjects.html
// ======
boost 中的 function,bind ,shared_from_this 这三个方法常常会在一起使用,
并且经常用在回调函数中。这里所说的回调函数就是在一个主函数中,根据不同的情景来通过函数指针来调用不同情景下面的函数。
普通 c++98 通过函数指针来实现回调函数的示例
online_compiler
点击(此处)折叠或打开
#include <iostream>
#include <cstdio>
using namespace std ;
typedef void (* fun_t)(void) ;
void fun0(void)
{
cout << "fun0 called " << endl ;
}
void fun1 ( void )
{
cout << "fun1 called " << endl ;
}
void fun2 ( void )
{
cout << "fun2 called " << endl ;
}
void (*cb_fun_list[3])(void) = {fun0 ,fun1 , fun2} ;
void call_back ( int i )
{
fun_t funPtr ;
if (i < 0 || i > 2 )
{
cout << " illegal function number " << endl ;
return ;
}
funPtr = cb_fun_list[i] ;
funPtr () ;
}
int main ()
{
call_back ( 2 ) ;
call_back ( 0 ) ;
call_back ( 1 ) ;
return 0 ;
}
boost 使用示例
online_compiler
个人觉得下面的这个例子除了演示,bind 如何绑定带有参数的方法,并将其与以 function<...> 为参数的
方法对接之外,还有如何使用 shared_from_this () 没有实用价值,
因为我们在编程中很少会用到,类自己定义一个回调函数来回调自己类中的成员方法的。
回调方法通常应用与2或2个以上的类(结构体) 中的一个类中需要调用bind 方法而需要获得另一个类的对象实例传入
这种情况。比如说第三个例子中所讲的那样,不过第三个例子中没有实现 bind 方法中关于参数传递的处理。
关于 shared_from_this () , 这个方法通常是在类内部来使用,这个方法是用来返回一个 shared_ptr<T> 的指针,
也就是我们常使用到的“智能指针”中最有用的。同时如果要想让 shared_ptr<T> 对应的 T 是当前类的类型的话,
应该让当前的类继承 boost::enable_shared_from_this 这个类作为基类,同时在 enabled_shared_from_this
后面类模板声明的时候,传入当前的类 , 即
class TestObj : public boost::enable_shared_from_this <TestObj>
{....} ;
还有一点值得注意的便是:
通过上述方法声明的类实例的创建,不能够使用简单的
TestObj testObj (...);
TestObj *testObjPtr = new TestObj () ;
这种方法进行创建,因为 TestObj 继承了 enable_shared_from_this ,
所以它的初始化方法必须要在某种程度上按照 boost::enable_shared_from_this 的套路来,
所以,应该使用 shared_ptr 的方法来创建指向该对象的指针对象,然后通过指针对象来调用类实例中声明、定义一系列的方法。
点击(此处)折叠或打开
#include <iostream>
#include <cstdio>
#include <boost/function.hpp>
#include <boost/bind.hpp>
#include <boost/enable_shared_from_this.hpp>
using namespace std ;
class obj : public boost::enable_shared_from_this<obj>
{
public :
void runCallBack ( boost::function<int(int,int)> f , int x , int y )
{
cout << f( x, y ) << endl ;
}
int myadd ( int x , int y )
{
return x+y ;
}
void setCallBack ( int x , int y )
{
runCallBack( boost::bind( &obj::myadd , shared_from_this () , _1 , _2 ) ,x , y ) ;
}
private :
boost::function<int( int ,int )> f;
} ;
int main ()
{
boost::shared_ptr<obj> pObj ( new obj ()) ;
pObj->setCallBack(999, 1) ;
return 0 ;
}
boost 使用实例
虽然这仅仅是个简单的例子,但是我们可以把情况想象的更加复杂一些,
比如说 Manager 相当于是 RPC 框架中的服务器端的方法调用引擎,
当 Client 端给出需要远程调用的 function -- name , parameter-list 之后,将这些消息通过 socket 封装成消息
传递给服务器端的时候,服务器端的引擎 Manager 可以根据 function <>这个方法来锁定到应该调用哪一个方法来运行。
并把运行之后的结果同样包装成消息,并通过 socket 回复给请求的client。
不过上述的描述还需要大量的代码作为支撑,比如 client server 之间需要定义通信的协议以及 RPC 远程调用的方法的接口描述文件。
这个接口描述文件,可以将它们理解为 server 端为 client 端所提供的可调用方法的清单,同时 server 端可以通过类似于 register
的方法来将所有的方法函数以 function <> 的方式传入到一个 std::vector<function<> > 里面.
online_compiler
点击(此处)折叠或打开
#include <boost/shared_ptr.hpp>
#include <boost/enable_shared_from_this.hpp>
#include <boost/function.hpp>
#include <boost/bind.hpp>
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <string>
#include <vector>
using namespace std ;
using namespace boost ;
class Manager
{
public :
Manager ( )
{}
void registerCallBack ( boost::function<void ()> f )
{
cout << " in manager call input function " << endl ;
fds.push_back(f) ;
}
void runCallBack ()
{
cout<< "running method defined in Node" << endl ;
for ( int i = 0;i < fds.size() ; i++ )
{
boost::function<void()> f = fds[i] ;
f() ;
}
fds.clear() ;
}
private :
std::vector<boost::function<void()> > fds ;
} ;
class Node : public boost::enable_shared_from_this<Node>
{
public :
Node () {}
Node ( Manager *managerPtr )
{
pManager = managerPtr ;
}
void Aimer ( )
{
cout << " Aimer : hello i am Aimer " << endl ;
}
void Kokia ( )
{
cout << " Kokia : hello i am Kokia " << endl ;
}
void Kylin ( )
{
cout << " Kylin Zhang : ..... - _ - ......" << endl ;
}
void start ()
{
cout << " in method start " << endl ;
pManager->registerCallBack(boost::bind(&Node::Aimer , shared_from_this() )) ;
pManager->registerCallBack(boost::bind(&Node::Kokia , shared_from_this())) ;
pManager->registerCallBack(boost::bind (&Node::Kylin , shared_from_this ())) ;
}
Manager *pManager ;
} ;
class Obj : public boost::enable_shared_from_this<Obj>
{
public :
Obj ( Manager *pManager )
{
managerPtr = pManager ;
}
void start()
{
managerPtr->registerCallBack( boost::bind (&Obj::func1 , shared_from_this ()) ) ;
managerPtr->registerCallBack( boost::bind ( &Obj::func2 , shared_from_this () )) ;
}
void func1()
{
cout << "func1 running "<< endl ;
}
void func2 ()
{
cout << "func 2 running " << endl ;
}
private :
Manager* managerPtr ;
} ;
int main ()
{
Manager* pManager = new Manager() ;
boost::shared_ptr<Node> nodePtr ( new Node ( pManager) ) ;
boost::shared_ptr<Obj> objPtr ( new Obj (pManager) ) ;
cout << " now i would like register methods defined in class Node into Manager function<void()> list " << endl ;
nodePtr->start() ;
cout << " now register methods in class Obj into Manager , by input parameter the pointer of class Manager instance " <<endl ;
objPtr->start () ;
cout <<" ------------------------ run method----------------------------" << endl ;
pManager->runCallBack() ;
return 0 ;
}
end
函数对象,成为‘高阶函数’,可以呗传入到其他函数或者从其他函数返回的一类函数。
Boost.Bind可替换来自c++标准中的std::bind1st()和std::bind2dn()函数
Boost.Function则提供了一个用于封装函数指针的类。
Boost.Lambda引入了一种创建匿名函数的方法。
===
bind提供了一种机制,将这些函数与不限数量的参数一起使用,可以得到指定签名的函数。
//=====
#include <iostream>
#include <boost/thread/thread.hpp>
#include <boost/bind.hpp>
#include <vector>
#include <algorithm>
void hello(){
std::cout<<"hello world,I'm a thread from boost library"<<std::endl;
}
using namespace std;
void add(int i,int j){
std::cout<<i+j<<std::endl;
}
int main() {
std::vector<int> v;
v.push_back(1);
v.push_back(2);
v.push_back(3);
std::for_each(v.begin(),v.end(),boost::bind(add,10,_1));
return 0;
}
//======
_1被称为占位符(placeholder),定义于boost.bind。除了_1,boost.bind还定义了_2和_3。通过这些占位符,bind可以变为一元、二元或者三元的函数。对于_1,boost::bind变为一个一元函数(即只要求一个参数的函数)。因为for_each(只要求一个一元函数作为其第三个参数。)
ps:简单来说,_1指代的是vector中的元素值,作为add函数的第一个参数,10默认作为第二个参数。bind的第一个参数值是add函数名字。
======
如果用于boost::bind()的函数带有至少一个引用参数时,Boost.Ref就重要了。因为bind会复制它的参数,引用必须特殊处理。
<boost/ref.hpp>
std::for_each(v.begin(), v.end(), boost::bind(add, 10, _1, boost::ref(std::cout)));
=======
boost.function()的功能,为了封装函数指针;
位于boost/function.hpp中,
用法是:boost::function<int (const char*)>f= std::strlen;
定一个函数指针,表示此函数接受的参数类型为const char*,返回的参数类型为int。定义完成后,匹配此签名的函数都可以复制给这个指针。
因为f是一个函数指针,被赋值的函数可以通过重载的operator()()操作符来调用。
另外当f未被赋值,而被调用的,会发生boost::bad_function_call异常。
//======
#include <iostream>
#include <boost/thread/thread.hpp>
#include <boost/bind.hpp>
#include <vector>
#include <algorithm>
#include <boost/function.hpp>
#include <cstdlib>
#include <cstring>
struct world{
void hello(std::ostream &os){
os <<"helllo,world"<<std::endl;
}
};
int main() {
boost::function<int (const char*)> f = std::atoi;
std::cout<<f("1292")<<endl;
f = std::strlen;
std::cout<<f("1609")<<std::endl;
try {
boost::function<int (const char*)> f2;
f2("");
}catch (boost::bad_function_call &ex){
cout<<ex.what()<<endl;
}
boost::function<void (world*,std::ostream &)> f3 = &world::hello;
world w;
f3(&w,boost::ref(std::cout));
return 0;
}
//======
=====
参考:http://zh.highscore.de/cpp/boost/functionobjects.html
// ======
boost 中的 function,bind ,shared_from_this 这三个方法常常会在一起使用,
并且经常用在回调函数中。这里所说的回调函数就是在一个主函数中,根据不同的情景来通过函数指针来调用不同情景下面的函数。
普通 c++98 通过函数指针来实现回调函数的示例
online_compiler
点击(此处)折叠或打开
#include <iostream>
#include <cstdio>
using namespace std ;
typedef void (* fun_t)(void) ;
void fun0(void)
{
cout << "fun0 called " << endl ;
}
void fun1 ( void )
{
cout << "fun1 called " << endl ;
}
void fun2 ( void )
{
cout << "fun2 called " << endl ;
}
void (*cb_fun_list[3])(void) = {fun0 ,fun1 , fun2} ;
void call_back ( int i )
{
fun_t funPtr ;
if (i < 0 || i > 2 )
{
cout << " illegal function number " << endl ;
return ;
}
funPtr = cb_fun_list[i] ;
funPtr () ;
}
int main ()
{
call_back ( 2 ) ;
call_back ( 0 ) ;
call_back ( 1 ) ;
return 0 ;
}
boost 使用示例
online_compiler
个人觉得下面的这个例子除了演示,bind 如何绑定带有参数的方法,并将其与以 function<...> 为参数的
方法对接之外,还有如何使用 shared_from_this () 没有实用价值,
因为我们在编程中很少会用到,类自己定义一个回调函数来回调自己类中的成员方法的。
回调方法通常应用与2或2个以上的类(结构体) 中的一个类中需要调用bind 方法而需要获得另一个类的对象实例传入
这种情况。比如说第三个例子中所讲的那样,不过第三个例子中没有实现 bind 方法中关于参数传递的处理。
关于 shared_from_this () , 这个方法通常是在类内部来使用,这个方法是用来返回一个 shared_ptr<T> 的指针,
也就是我们常使用到的“智能指针”中最有用的。同时如果要想让 shared_ptr<T> 对应的 T 是当前类的类型的话,
应该让当前的类继承 boost::enable_shared_from_this 这个类作为基类,同时在 enabled_shared_from_this
后面类模板声明的时候,传入当前的类 , 即
class TestObj : public boost::enable_shared_from_this <TestObj>
{....} ;
还有一点值得注意的便是:
通过上述方法声明的类实例的创建,不能够使用简单的
TestObj testObj (...);
TestObj *testObjPtr = new TestObj () ;
这种方法进行创建,因为 TestObj 继承了 enable_shared_from_this ,
所以它的初始化方法必须要在某种程度上按照 boost::enable_shared_from_this 的套路来,
所以,应该使用 shared_ptr 的方法来创建指向该对象的指针对象,然后通过指针对象来调用类实例中声明、定义一系列的方法。
点击(此处)折叠或打开
#include <iostream>
#include <cstdio>
#include <boost/function.hpp>
#include <boost/bind.hpp>
#include <boost/enable_shared_from_this.hpp>
using namespace std ;
class obj : public boost::enable_shared_from_this<obj>
{
public :
void runCallBack ( boost::function<int(int,int)> f , int x , int y )
{
cout << f( x, y ) << endl ;
}
int myadd ( int x , int y )
{
return x+y ;
}
void setCallBack ( int x , int y )
{
runCallBack( boost::bind( &obj::myadd , shared_from_this () , _1 , _2 ) ,x , y ) ;
}
private :
boost::function<int( int ,int )> f;
} ;
int main ()
{
boost::shared_ptr<obj> pObj ( new obj ()) ;
pObj->setCallBack(999, 1) ;
return 0 ;
}
boost 使用实例
虽然这仅仅是个简单的例子,但是我们可以把情况想象的更加复杂一些,
比如说 Manager 相当于是 RPC 框架中的服务器端的方法调用引擎,
当 Client 端给出需要远程调用的 function -- name , parameter-list 之后,将这些消息通过 socket 封装成消息
传递给服务器端的时候,服务器端的引擎 Manager 可以根据 function <>这个方法来锁定到应该调用哪一个方法来运行。
并把运行之后的结果同样包装成消息,并通过 socket 回复给请求的client。
不过上述的描述还需要大量的代码作为支撑,比如 client server 之间需要定义通信的协议以及 RPC 远程调用的方法的接口描述文件。
这个接口描述文件,可以将它们理解为 server 端为 client 端所提供的可调用方法的清单,同时 server 端可以通过类似于 register
的方法来将所有的方法函数以 function <> 的方式传入到一个 std::vector<function<> > 里面.
online_compiler
点击(此处)折叠或打开
#include <boost/shared_ptr.hpp>
#include <boost/enable_shared_from_this.hpp>
#include <boost/function.hpp>
#include <boost/bind.hpp>
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <string>
#include <vector>
using namespace std ;
using namespace boost ;
class Manager
{
public :
Manager ( )
{}
void registerCallBack ( boost::function<void ()> f )
{
cout << " in manager call input function " << endl ;
fds.push_back(f) ;
}
void runCallBack ()
{
cout<< "running method defined in Node" << endl ;
for ( int i = 0;i < fds.size() ; i++ )
{
boost::function<void()> f = fds[i] ;
f() ;
}
fds.clear() ;
}
private :
std::vector<boost::function<void()> > fds ;
} ;
class Node : public boost::enable_shared_from_this<Node>
{
public :
Node () {}
Node ( Manager *managerPtr )
{
pManager = managerPtr ;
}
void Aimer ( )
{
cout << " Aimer : hello i am Aimer " << endl ;
}
void Kokia ( )
{
cout << " Kokia : hello i am Kokia " << endl ;
}
void Kylin ( )
{
cout << " Kylin Zhang : ..... - _ - ......" << endl ;
}
void start ()
{
cout << " in method start " << endl ;
pManager->registerCallBack(boost::bind(&Node::Aimer , shared_from_this() )) ;
pManager->registerCallBack(boost::bind(&Node::Kokia , shared_from_this())) ;
pManager->registerCallBack(boost::bind (&Node::Kylin , shared_from_this ())) ;
}
Manager *pManager ;
} ;
class Obj : public boost::enable_shared_from_this<Obj>
{
public :
Obj ( Manager *pManager )
{
managerPtr = pManager ;
}
void start()
{
managerPtr->registerCallBack( boost::bind (&Obj::func1 , shared_from_this ()) ) ;
managerPtr->registerCallBack( boost::bind ( &Obj::func2 , shared_from_this () )) ;
}
void func1()
{
cout << "func1 running "<< endl ;
}
void func2 ()
{
cout << "func 2 running " << endl ;
}
private :
Manager* managerPtr ;
} ;
int main ()
{
Manager* pManager = new Manager() ;
boost::shared_ptr<Node> nodePtr ( new Node ( pManager) ) ;
boost::shared_ptr<Obj> objPtr ( new Obj (pManager) ) ;
cout << " now i would like register methods defined in class Node into Manager function<void()> list " << endl ;
nodePtr->start() ;
cout << " now register methods in class Obj into Manager , by input parameter the pointer of class Manager instance " <<endl ;
objPtr->start () ;
cout <<" ------------------------ run method----------------------------" << endl ;
pManager->runCallBack() ;
return 0 ;
}
end
相关文章推荐
- boost::bind绑定成员函数时,第一个参数传递对象的特殊情况
- 共享boost::deadline_timer封装模板,可以接受任何函数对象
- boost::thread 使用函数对象来构造线程对象的问题
- boost函数对象的妙用
- boost::bind会返回一个函数对象,它内部保存了数据的拷贝
- boost python 函数中传递对象
- Boost Part III. 函数对象与高级编程 Library 10. Lambda 用法
- Boost Part III. 函数对象与高级编程 Library 10. Lambda 用法 switch_statement
- Boost 函数对象
- 函数对象function object 以及boost::bind的一点了解
- Boost学习------函数对象
- Boost关于bind的使用以及函数对象和传递参数的问题
- Boost学习系列3-函数对象(上)
- 你注意到C++的函数对象都是传值的形式了吗?---boost::ref的强大用处~
- Boost学习系列3-函数对象(下)
- C++ boost 组件简介:函数对象及高级编程
- boost 函数对象和高阶编程概述
- Boost库中的函数对象
- Boost.Bind用法详解(一) 2008-05-09 15:50:50| 分类: C++ |字号 订阅 Boost.Bind 为函数和函数对象提供了一致的语法,对于值语义和指针语义也一样。
- 【C++】boost::bind和函数对象一起使用实现便捷的异步编程