ImageVerifierCode 换一换
格式:DOC , 页数:74 ,大小:608KB ,
资源ID:7993875      下载积分:10 金币
验证码下载
登录下载
邮箱/手机:
验证码: 获取验证码
温馨提示:
支付成功后,系统会自动生成账号(用户名为邮箱或者手机号,密码是验证码),方便下次登录下载和查询订单;
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

开通VIP
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.zixin.com.cn/docdown/7993875.html】到电脑端继续下载(重复下载【60天内】不扣币)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  
声明  |  会员权益     获赠5币     写作写作

1、填表:    下载求助     留言反馈    退款申请
2、咨信平台为文档C2C交易模式,即用户上传的文档直接被用户下载,收益归上传人(含作者)所有;本站仅是提供信息存储空间和展示预览,仅对用户上传内容的表现方式做保护处理,对上载内容不做任何修改或编辑。所展示的作品文档包括内容和图片全部来源于网络用户和作者上传投稿,我们不确定上传用户享有完全著作权,根据《信息网络传播权保护条例》,如果侵犯了您的版权、权益或隐私,请联系我们,核实后会尽快下架及时删除,并可随时和客服了解处理情况,尊重保护知识产权我们共同努力。
3、文档的总页数、文档格式和文档大小以系统显示为准(内容中显示的页数不一定正确),网站客服只以系统显示的页数、文件格式、文档大小作为仲裁依据,个别因单元格分列造成显示页码不一将协商解决,平台无法对文档的真实性、完整性、权威性、准确性、专业性及其观点立场做任何保证或承诺,下载前须认真查看,确认无误后再购买,务必慎重购买;若有违法违纪将进行移交司法处理,若涉侵权平台将进行基本处罚并下架。
4、本站所有内容均由用户上传,付费前请自行鉴别,如您付费,意味着您已接受本站规则且自行承担风险,本站不进行额外附加服务,虚拟产品一经售出概不退款(未进行购买下载可退充值款),文档一经付费(服务费)、不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
5、如你看到网页展示的文档有www.zixin.com.cn水印,是因预览和防盗链等技术需要对页面进行转换压缩成图而已,我们并不对上传的文档进行任何编辑或修改,文档下载后都不会有水印标识(原文档上传前个别存留的除外),下载后原文更清晰;试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓;PPT和DOC文档可被视为“模板”,允许上传人保留章节、目录结构的情况下删减部份的内容;PDF文档不管是原文档转换或图片扫描而得,本站不作要求视为允许,下载前自行私信或留言给上传者【pc****0】。
6、本文档所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用;网站提供的党政主题相关内容(国旗、国徽、党徽--等)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
7、本文档遇到问题,请及时私信或留言给本站上传会员【pc****0】,需本站解决可联系【 微信客服】、【 QQ客服】,若有其他问题请点击或扫码反馈【 服务填表】;文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“【 版权申诉】”(推荐),意见反馈和侵权处理邮箱:1219186828@qq.com;也可以拔打客服电话:4008-655-100;投诉/维权电话:4009-655-100。

注意事项

本文(BOOST应用初探.doc)为本站上传会员【pc****0】主动上传,咨信网仅是提供信息存储空间和展示预览,仅对用户上传内容的表现方式做保护处理,对上载内容不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知咨信网(发送邮件至1219186828@qq.com、拔打电话4008-655-100或【 微信客服】、【 QQ客服】),核实后会尽快下架及时删除,并可随时和客服了解处理情况,尊重保护知识产权我们共同努力。
温馨提示:如果因为网速或其他原因下载失败请重新下载,重复下载【60天内】不扣币。 服务填表

BOOST应用初探.doc

1、BOOST应用初探作者:冯刚2011-8-41 背景BOOST是由c+标准化委员会成员参与开发的c+标准的准官方库,他是C+标准库的发动机。下一代C+标准C+0x的标准库很多来自于boost。Boost库覆盖了广泛的领域,从数学库到智能指针,从模板元编程库到预处理器库及语法词法分析,从线程到lambda表达式,等等。所有Boost库都具有宽松的许可证,确保库可以被自由使用于商用软件。2 功能2.1 概况Boost库涵盖了很广泛的领域,下面就常用的功能像智能指针,正则表达式,函数对象bind和function, 线程和线程池,时间日期,多索引容器,哈希容器,bimap,日志,内存池,模板元编程,

2、循环缓冲区,tuple, 观察者模式signal2,网络通讯asio做一些介绍。2.2 功能2.2.1 智能指针2.2.1.1 概论smart pointers(智能指针)是存储“指向动态分配(在堆上)的对象的指针”的对象。他们的行为很像 C+ 的内建指针,只是它们可以在适当的时候自动删除它们所指向的对象。智能指针在面对异常时有非常显著的作用,它们可以确保动态分配对象的完全析构。它们还可以用于跟踪多主人共享的动态分配对象。在概念上,智能指针可以看作拥有它所指向的对象,并因此在对象不再需要时负责将它删除。智能指针库提供了六个智能指针类模板:scoped_ptr简单的单一对象的唯一所有权。不可拷贝

3、。scoped_array简单的数组的唯一所有权。不可拷贝。shared_ptr在多个指针间共享的对象所有权。shared_array在多个指针间共享的数组所有权。weak_ptr一个属于 shared_ptr 的对象的无所有权的观察者。intrusive_ptr带有一个侵入式引用计数的对象的共享所有权。这些模板被设计用来补充 std:auto_ptr 模板的不足。2.2.1.2 智能指针shared_ptrshared_ptr 类模板存储一个指向动态分配对象(一般是用 C+ new-expression 生成的)的指针。在最后一个 shared_ptr 所指向的对象被销毁或重置时,要保证它所

4、指向的对象被删除。每一个 shared_ptr 都符合 C+ 标准库的 CopyConstructible 和 Assignable 的必要条件,并因此能够用于标准库容器。因为提供了比较操作,因此 shared_ptr 可以和标准库中的关联式容器一起工作。通常,一个 shared_ptr 不能正确地持有一个指向动态分配的数组的指针。关于那种用法请参见 shared_array。因为在实现中使用了引用计数,shared_ptr实例的循环引用不会被回收。例如,如果 main() 持有一个指向 A 的 shared_ptr, A 又直接或间接持有一个指回 A 的 shared_ptr,A 的使用计数

5、是 2。最初的 shared_ptr 析构后将导致一个使用计数为 1 的 A 被悬挂。使用 weak_ptr 以“打破循环”。这个类模板被 T 参数化,T 是被指向的对象的类型。shared_ptr 和它的大多数成员函数对于 T 没什么要求,允许它是一个不完整类型,或者为 void。对 T 有附加要求的成员函数 (constructors, reset) 都明确地记录在下面。只要 T* 能被隐式地转换到 U*,则 shared_ptr 就能被隐式地转换到 shared_ptr。特别是,shared_ptr 隐式转换到 shared_ptr,当 U 是 T 的一个可访问基类的时候,还能转换到 s

6、hared_ptr,以及转换到 shared_ptr。惯用手法由于智能指针是线程安全的,建议在代码里只为一个对象生成单一的shared_ptr,在多线程环境中传递参数时使用weak_ptr,这样当shared_ptr被析构,weak_ptr也会得到通知,变为无效,这样可以有效地防止野指针,同时也防止了潜在的循环引用,无法释放对象的问题。shared_ptr spA = shared_ptr(new A);int func(weak_ptr wpA)If(!wpA.expired())/正常处理逻辑shared_ptr spA = wpA.lock();/Use spAelse/智能指针已被其他

7、线程释放func(spA);2.2.1.3 智能指针weak_ptr简介weak_ptr是Boost智能指针shared_ptr的一个重要伙伴。它允许打破循环依赖。另外,它还可以处理一个非常常见的问题悬空指针。当销毁最后一个智能指针shared_ptr,它会释放掉共享的资源。通过使用智能指针weak_ptr,这方面的信息会传播给所有观察该共享资源的智能指针weak_ptr,通过weak_ptr可以知道该共享资源已经释放,这意味着不会发生无意间访问无效指针的情形。这就是观察者模式的一个特例,也就是说,当销毁资源的时候,就会通知所有对资源感兴趣的weak_ptr,通过调用weak_ptr.expi

8、red(),当返回值为true时,就表示该共享资源已经释放了。weak_ptr 类模板存储一个引向已被 shared_ptr 管理的对象的 weak reference(弱引用)。为了访问这个对象,一个 weak_ptr 可以利用 shared_ptr 的构造函数或成员函数 lock 转换为 shared_ptr。当最后一个指向对象的 shared_ptr 消失,而对象也被删除后,从一个引向已被删除对象的 weak_ptr 实例获取 shared_ptr 的企图就会失败:构造函数会抛出一个 boost:bad_weak_ptr 类型的异常,而 weak_ptr:lock 会返回一个 empty

9、 shared_ptr。每一个 weak_ptr 都符合 C+ 标准库的 CopyConstructible 和 Assignable 的必要条件,并因此能够用于标准库容器。因为提供了比较操作,因此 weak_ptr 可以和标准库中的关联式容器一起工作。weak_ptr 的操作绝不会抛出异常。这个类模板被 T 参数化,T 是被指向的对象的类型。相对于 shared_ptr,weak_ptr 提供了一个非常有限的操作子集,因为在多线程程序中访问它所存储的指针是非常危险的,甚至有时在一个单线程程序中也是不安全的(也就是说,它可能引起未定义行为)。姑且假设 weak_ptr 有一个返回 raw po

10、inter(裸指针)的 get 成员函数,考虑下面这个无辜的代码片段:shared_ptr p(new int(5);weak_ptr q(p);/ some time laterif(int * r = q.get() / use *r设想在 if 之后,但是又恰恰在 r 被使用之前,另一个线程执行了语句 p.reset()。这样 r 就成了一个 dangling pointer(悬挂指针)。解决这个问题的方案是从 q 创建一个临时的 shared_ptr:shared_ptr p(new int(5);weak_ptr q(p);/ some time laterif(shared_ptr

11、 r = q.lock() / use *r这样,r 就持有一个引向 q 所指向的对象的引用。即使在其它线程中执行了 p.reset(),那个对象也会继续活着,直到 r 离开作用域或者被 reset。通过获得一个指向这个对象的 shared_ptr,我们可以有效地保住它不被析构。2.2.2 正则表达式xpressive 是一个先进的、面向对象的、用于C+的正则表达式模板库。正则表达式可以以字符串方式编写并在运行期分析,也可以以表达式模板方式编写并在编译期分析。正则表达式可以相互引用,或者递归引用其本身,你就可以用它们来构建任意复杂的语法。它与Boost.Regex库的区别就是无需编译,全模板库

12、。如果你要在C+中处理文本,通常你有两个不相交的选项:正则表达式引擎或语法分析生成器。正则表达式引擎(如 Boost.Regex)更为强大和灵活;文本的模式以字符串方式表示,可以在运行期指定。但是,这意味着语法错误同样要到运行期才能被检测。另外,正则表达式不适合于高级的文本处理任务,如匹配平衡的、嵌套的标签。那些任务传统上都是由语法分析生成器(如 Spirit 语法分析器框架)来处理的。这些工具更为强大,但不够灵活。它们通常不允许你随时随意地修改你的语法规则。此外,它们不具备正则表达式的完全回溯语义,对于某些类型的模式来说,这样对作者更具有挑战性。将这两种方法无缝地集合到一起,在C+的文本处理

13、世界中占据了独特的优势。通过 xpressive,你可以选择更象使用 Boost.Regex 那样去使用它,将正则表达式表示为字符串。或者你也可以象使用 Spirit 那样使用它,将你的 regexes 写为C+表达式,获得一种专用于文本处理的嵌入式语言所带来的所有好处。更重要的是,你可以混用这两种方式,从而获得两者的好处,对于那些要静态绑定的正则表达式编写正则表达式语法 - 由编译器进行硬编码和语法检查 - 其它的则动态绑定并在运行期指定。这些正则表达式可以相互递归地引用,在以前的正则表达式不能进行模式匹配的字符串中进行模式匹配。Xpressive 是一个只含头文件的模板库,这意味着你不需要

14、修改你的构建脚本或链接任何独立的lib文件就可以使用它。你所要做的就是 #include 。如果你只使用静态 regexes,你可以只包含 xpressive_static.hpp 以提高编译速度。同样,如果你计划只使用动态regexes,则可以只包含 xpressive_dynamic.hpp。表28.1.xpressive的工具箱Tool 工具 Description 说明 basic_regex 含有一个已编译的正则表达式。basic_regex 是xpressive之中最重要的类型。你用xpressive做的任何事情都要从创建一个类型为 basic_regex 的对象开始。 match

15、_results, sub_match match_results 含有 regex_match() 或 regex_search() 操作的结果。它就象一个存有 sub_match 对象的向量。一个 sub_match 对象含有一个已标记的子表达式(在Perl中又称为后向引用)。基本上,它只是一个迭代器对,代表了已标记子表达式的开始和结束。 regex_match() 检查一个字符串是否匹配一个regex。regex_match() 要成功,必须是整个字符串从头到尾匹配regex。如果你给了 regex_match() 一个 match_results,那么它会将所有找到的带标记子表达式写入

16、其中。 regex_search() 查找一个字符串,以发现其中匹配regex的子字符串。regex_search() 将尝试在字符串的每个位置查找匹配,从头部开始,当找到一个匹配或者整个字符串找完时停止。使用 regex_match() 时,如果你给了 regex_search() 一个 match_results,那么它会将所有找到的带标记子表达式写入其中。 regex_replace() 给定一个输入字符串,一个regex和一个替代字符串,regex_replace() 通过将输入字符串中与regex相匹配的部分替换为替代字符串来构建一个新的字符串。替代字符串可以含有对带标记子表达式的引

17、用。 regex_iterator 一个与STL兼容的迭代器,可以很方便地找到在一个字符串中与某个regex匹配的所有地方。解引用一个 regex_iterator 会返回一个 match_results。递增一个 regex_iterator 可以找出下一个匹配。 regex_token_iterator 类似于 regex_iterator,除了一点,解引用一个 regex_token_iterator 会返回一个字符串。缺省地,它返回与regex匹配的整个子字符串,不过它也可以被配置为每次返回任一个或整个带标记子表达式,或者甚至是不匹配 regex的部分字符串。 regex_compil

18、er 一个用于 basic_regex 对象的工厂。它将一个字符串编译为正则表达式。通常,你不需要直接关心 regex_compiler,因为 basic_regex 类有一个工厂方法,其内部使用了 regex_compiler。不过,如果你需要做一些花哨的东西,如创建一个带有不同 std:locale 的 basic_regex 对象,你就需要显式使用 regex_compiler 了。 现在你应该对xpressive所提供的工具有了一些了解,你可以通过回答以下两个问题来找到合适的工具: 1. 你要用哪种类型的迭代器来遍历你的数据? 2. 你要对你的数据做什么操作? 弄明白你的迭代器类型 在

19、xpressive中的多数类都是根据迭代器类型参数化的模板类。xpressive定义了一些常用的typedefs来让你可以更容易地选择合适的类型。你可以用下表基于你的迭代器类型来找到正确的类型。 下表为xpressive Typedefs 与迭代器类型std:string:const_iterator char const * std:wstring:const_iterator wchar_t const * basic_regex sregex cregex wsregex wcregex match_results smatch cmatch wsmatch wcmatch regex_

20、compiler sregex_compiler cregex_compiler wsregex_compiler wcregex_compiler regex_iterator sregex_iterator cregex_iterator wsregex_iterator wcregex_iterator regex_token_iterator sregex_token_iterator cregex_token_iterator wsregex_token_iterator wcregex_token_iterator 你要留意系统的命名习惯。这些类型经常要一起使用,所以命名习惯可以帮

21、助你一致地使用它们。例如,如果你有一个 sregex,你就应该使用 smatch。 如果你用的不是以上四种迭代器类型之一,那么你可以直接用模板并指定你的迭代器类型。示例 以下你将看到六个完整的示例程序。 检查整个字符串是否匹配一个regex 这是来自于简介一节中的示例。为便于查看,在此重复。 #include #include using namespace boost:xpressive;int main()std:string hello( hello world! );sregex rex = sregex:compile( (w+) (w+)! );smatch what;if( re

22、gex_match( hello, what, rex ) )std:cout what0 n; / whole match 整个匹配 std:cout what1 n; / first capture 第一次捕获 std:cout what2 n; / second capture 第二次捕获 return 0;程序输出如下: hello world!helloworld检查一个字符串是否包含匹配某个regex的子串 请留意在这个例子中,我们是如何使用定制的 mark_tags 来使得匹配的模式更可读。我们可以在稍后使用 mark_tags 来对 match_results 进行索引访问。

23、#include #include using namespace boost:xpressive;int main()char const *str = I was born on 5/30/1973 at 7am.;/ 以名字定义一些定制的 mark_tags,比 s1, s2 等更有意义。 mark_tag day(1), month(2), year(3), delim(4);/该regex查找一个日期 cregex date = (month= repeat(_d) / 查找月份. (delim= (set= /,-) / 后跟一个分隔符. (day= repeat(_d) deli

24、m / 和一个日期再跟一个分隔符. (year= repeat(_d _d); /和年份。cmatch what;if( regex_search( str, what, date ) )std:cout what0 n; / whole match 全匹配 std:cout whatday n; / the day 日期 std:cout whatmonth n; / the month 月份 std:cout whatyear n; / the year 年份 std:cout whatdelim n; / the delimiter 分隔符 return 0;This program o

25、utputs the following:程序输出如下: 5/30/19733051973/替换匹配某个regex的所有子串 以下程序在一个字符串中查找日期并用伪-HTML标记它们。 #include #include using namespace boost:xpressive;int main()std:string str( I was born on 5/30/1973 at 7am. );/ 基本上与上一个例子中的regex相同,但用的是动态regex sregex date = sregex:compile( (d1,2)(/-)(d1,2)2(?:d2)1,2) );/ 和在P

26、erl中一样,$& 是指向匹配该regex的子串的引用 std:string format( $& );str = regex_replace( str, date, format );std:cout str n;return 0;程序输出如下: I was born on 5/30/1973 at 7am.查找匹配某个regex的所有子串并每次一个地分步处理它们 以下程序在一个宽字符串中查找单词。它使用 wsregex_iterator。注意,对 wsregex_iterator 的解引用将产生一个 wsmatch 对象。 #include #include using namespace

27、 boost:xpressive;int main()std:wstring str( LThis is his face. );/查找一个完整的单词 wsregex token = +alnum;wsregex_iterator cur( str.begin(), str.end(), token );wsregex_iterator end;for( ; cur != end; +cur )wsmatch const &what = *cur;std:wcout what0 Ln;return 0;程序输出如下: Thisishisface将字符串分拆为匹配某个regex的记号 以下程序在

28、字符串中查找比赛时间,并且先显示分钟数再显示秒数。它使用 regex_token_iterator. #include #include using namespace boost:xpressive;int main()std:string str( Eric: 4:40, Karl: 3:35, Francesca: 2:32 );/查找比赛时间 sregex time = sregex:compile( (d):(dd) );/ 对于每个匹配,记号迭代器首先取出第一个被标记的子表达式的值,然后是第二个子表达式的值 int const subs = 1, 2 ;sregex_token_i

29、terator cur( str.begin(), str.end(), time, subs );sregex_token_iterator end;for( ; cur != end; +cur )std:cout *cur n;return 0;This program outputs the following:程序输出如下: 440335232用一个regex作为分隔符分拆字符串 以下程序接受一些带有html标记的文本,去掉其中的标记。它使用一个regex来匹配HTML标签,并用一个 regex_token_iterator 返回字符串中不匹配该regex的其余部分。 #includ

30、e #include using namespace boost:xpressive;int main()std:string str( Now is the time for all good men to come to the aid of their country. );/ find a HTML tag 查找一个HTML标签 sregex html = optional(/) +_w ;/ 以下的 -1 指示记号迭代器显示字符串中不匹配正则表达式的部分。 sregex_token_iterator cur( str.begin(), str.end(), html, -1 );sr

31、egex_token_iterator end;for( ; cur != end; +cur )std:cout *cur ;std:cout n;return 0;程序输出如下: Now is the time for all good men to come to the aid of their country.显示嵌套结果组成的树 以下是一个辅助类,示范了如何显示由嵌套结果组成的树: /以缩入方式将嵌套结果输出至 std:coutstruct output_nested_resultsint tabs_;output_nested_results( int tabs = 0 ): t

32、abs_( tabs )templatevoid operator ()( match_results const &what ) const/首先进行缩入 typedef typename std:iterator_traits:value_type char_type;char_type space_ch = char_type( );std:fill_n( std:ostream_iterator( std:cout ), tabs_ * 4, space_ch );/输出匹配结果 std:cout what0 n;/输出嵌套的匹配 std:for_each(what.nested_re

33、sults().begin(),what.nested_results().end(),output_nested_results( tabs_ + 1 ) );2.2.3 Bind目的boost:bind 是标准函数 std:bind1st 和 std:bind2nd 的泛化。它支持任意的函数对象,函数,函数指针,和成员函数指针,它还能将任何参数绑定为一个特定的值,或者将输入的参数发送到任意的位置。bind 对函数对象没有任何要求,特别是,它不需要 result_type,first_argument_type 和 second_argument_type 这样的标准 typedefs。in

34、t f(int a, int b) return a + b;int g(int a, int b, int c) return a + b + c;bind(f, 1, 2) 会产生一个“无参数”函数对象,它不需要参数并返回 f(1, 2)。同样,bind(g, 1, 2, 3)() 等价于 g(1, 2, 3)。有选择性地只绑定一部分参数也是有可能的。bind(f, _1, 5)(x) 等价于 f(x, 5),这里,_1 是一个占位符参数,它的含义是“用第一个输入参数取代”。bind 能够处理带有两个以上参数的函数,而且它的参数取代机制更为直观:bind(f, _2, _1)(x, y);

35、 / f(y, x)bind(g, _1, 9, _1)(x); / g(x, 9, x)bind(g, _3, _3, _3)(x, y, z); / g(z, z, z)bind(g, _1, _1, _1)(x, y, z); / g(x, x, x)注意,最后一个示例中,由 bind(g, _1, _1, _1) 生成的函数对象不包含对第一个参数以外的任何参数的引用,但是它仍然能使用一个以上的参数。所有多余的参数被悄悄地忽略,就像在第三个示例中,第一和第二个参数被忽略。bind 持有的参数被返回的函数对象拷贝并内部持有。例如,在下面的代码中:int i = 5;bind(f, i, _

36、1);一个 i 的值的拷贝被存储于函数对象中。boost:ref 和 boost:cref 可用于让函数对象存储一个引用而不是拷贝:int i = 5;bind(f, ref(i), _1);bind(f, cref(42), _1);(和函数对象一起使用 bind)bind 并不限于函数,它可以接受任何函数对象。通常情况下,生成的函数对象的 operator() 的返回类型必须显式指定(没有 typeof 操作符,返回类型无法推导):struct F int operator()(int a, int b) return a - b; bool operator()(long a, long

37、 b) return a = b; ;F f;int x = 104;bind(f, _1, _1)(x);/ f(x, x), i.e. zero有些编译器遇到 bind(f, .) 语法会发生问题。出于可移植性的原因,一种和上面的意思相同的可选的表达方式也被支持:boost:bind(boost:type(), f, _1, _1)(x);但是要注意,这种可选语法只是作为一个 workaround 提供。它不是接口的一部分。当函数对象暴露了一个名为 result_type 的内嵌类型时,显式返回类型可以被省略:int x = 8;bind(std:less(), _1, 9)(x);/ x

38、 9【注意:这种省略返回类型的能力并非在所有的编译器上都可用。】缺省情况下,bind 为提供的函数对象做出一份拷贝。boost:ref 和 boost:cref 可用于让它存储这个函数对象的引用,而非拷贝。当函数对象是不可拷贝的,拷贝代价高昂,或者包含状态时是很有用的,当然,在这种情况下,要求程序员确保这个函数对象在使用期间不能被销毁。struct F2 int s; typedef void result_type; void operator()( int x ) s += x; ;F2 f2 = 0 ;int a = 1, 2, 3 ;std:for_each( a, a+3, bind

39、( ref(f2), _1 ) );assert( f2.s = 6 );(和成员指针一起使用 bind)成员函数的指针和数据成员的指针不是函数对象,因为它们不支持 operator()。为了方便起见,bind 接受成员指针作为它的第一个参数,而它的行为就像使用 boost:mem_fn 将成员指针转换成一个函数对象一样。换句话说,当 R 是 X:f 的返回类型(作为成员函数)或成员本身的类型(作为数据成员)时,表达式bind(&X:f, args)与bind(mem_fn(&X:f), args)等价。【注意:mem_fn 创建的函数对象可以接受一个对象的指针,引用或智能指针作为它的第一个参

40、数,更多的信息,参见 mem_fn 文档。】示例:struct X bool f(int a);X x;shared_ptr p(new X);int i = 5;bind(&X:f, ref(x), _1)(i);/ x.f(i)bind(&X:f, &x, _1)(i);/(&x)-f(i)bind(&X:f, x, _1)(i);/ (internal copy of x).f(i)bind(&X:f, p, _1)(i);/ (internal copy of p)-f(i)最后两个示例的有趣之处在于它们生成“自包含”的函数对象。bind(&X:f, x, _1) 存储 x 的一个拷贝

41、。bind(&X:f, p, _1) 存储 p 的一个拷贝,而且因为 p 是一个 boost:shared_ptr,这个函数对象保存一个属于它自己的 X 的实例的引用,而且当 p 离开它的作用域或者被 reset() 之后,这个引用依然保持有效。(为函数组合使用嵌套的 binds)传给 bind 的某些参数可以嵌套 bind 表达式自身:bind(f, bind(g, _1)(x); / f(g(x)当函数对象被调用的时候,如果没有指定顺序,内部 bind 表达式先于外部 bind 表达式被求值,在外部 bind 表达式被求值的时候,用内部表达式的求值结果取代它们的占位符的位置。在上面的示例中

42、,当用参数列表 (x) 调用那个函数对象的时候,bind(g, _1)(x) 首先被求值,生成 g(x),然后 bind(f, g(x)(x) 被求值,生成最终结果 f(g(x)。bind 的这个特性可被用来执行函数组合。参见示例 bind_as_compose.cpp,示范如何用 bind 达到与 Boost.Compose 类似的功能。注意第一个参数被绑定函数对象是不被求值的,即使它是一个由 bind 生成的函数对象或一个占位符参数,所以下面的示例不会如你所愿地工作:typedef void (*pf)(int);std:vector v;std:for_each(v.begin(), v.end(), bind(_1, 5);你所要的效果,可以通过将一个辅助函数对象 apply 用作它的第一个参数而获得,作为一个函数对象,它可以支撑它的参数列表。为了方便起见,在 boost/bind/apply.hpp 头文件中提供了一个 apply 的

移动网页_全站_页脚广告1

关于我们      便捷服务       自信AI       AI导航        获赠5币

©2010-2025 宁波自信网络信息技术有限公司  版权所有

客服电话:4008-655-100  投诉/维权电话:4009-655-100

gongan.png浙公网安备33021202000488号   

icp.png浙ICP备2021020529号-1  |  浙B2-20240490  

关注我们 :gzh.png    weibo.png    LOFTER.png 

客服