﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客-woaidongmao-随笔分类-Boost &amp; STL </title><link>http://www.cppblog.com/woaidongmao/category/6861.html</link><description>文章均收录自他人博客，但不喜标题前加-[转贴]，因其丑陋，见谅！~</description><language>zh-cn</language><lastBuildDate>Wed, 02 Sep 2009 21:11:19 GMT</lastBuildDate><pubDate>Wed, 02 Sep 2009 21:11:19 GMT</pubDate><ttl>60</ttl><item><title>使用std::vector 的陷阱</title><link>http://www.cppblog.com/woaidongmao/archive/2009/09/02/95146.html</link><dc:creator>肥仔</dc:creator><author>肥仔</author><pubDate>Wed, 02 Sep 2009 14:36:00 GMT</pubDate><guid>http://www.cppblog.com/woaidongmao/archive/2009/09/02/95146.html</guid><wfw:comment>http://www.cppblog.com/woaidongmao/comments/95146.html</wfw:comment><comments>http://www.cppblog.com/woaidongmao/archive/2009/09/02/95146.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/woaidongmao/comments/commentRss/95146.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/woaidongmao/services/trackbacks/95146.html</trackback:ping><description><![CDATA[<p style="text-justify: inter-ideograph; background: white; margin: 0cm 0cm 9pt; word-break: break-all; text-indent: 21pt; line-height: 150%; text-align: justify"><span style="color: black; mso-bidi-font-family: arial">在使用<span lang="EN-US">std</span>的容器的时候<span lang="EN-US">,</span>不少人喜欢用<span lang="EN-US">vector, </span>因为比起<span lang="EN-US">list,</span>更省空间<span lang="EN-US">,</span>而且可以根据<span lang="EN-US">index</span>直接读取某个值<span lang="EN-US">,</span>而不用一个个枚举来取<span lang="EN-US">.<?xml:namespace prefix = o /><o:p></o:p></span></span></p> <p style="text-justify: inter-ideograph; background: white; margin: 0cm 0cm 9pt; word-break: break-all; text-indent: 21pt; line-height: 150%; text-align: justify"><span style="color: black; mso-bidi-font-family: arial">但是<span lang="EN-US">,std::vector</span>确实有一些值得注意的陷阱<span lang="EN-US">, </span>这里先说其中一个<span lang="EN-US">, </span>请看以下代码<span lang="EN-US">.<o:p></o:p></span></span></p> <p style="text-justify: inter-ideograph; background: white; margin: 0cm 0cm 9pt; word-break: break-all; text-indent: 21pt; line-height: 150%; text-align: justify"><span lang="EN-US" style="color: black; mso-bidi-font-family: arial">std::vector&lt; int &gt;&nbsp; values;<o:p></o:p></span></p> <p style="text-justify: inter-ideograph; background: white; margin: 0cm 0cm 9pt; word-break: break-all; text-indent: 21pt; line-height: 150%; text-align: justify"><span lang="EN-US" style="color: black; mso-bidi-font-family: arial">values.push_back(1);<o:p></o:p></span></p> <p style="text-justify: inter-ideograph; background: white; margin: 0cm 0cm 9pt; word-break: break-all; text-indent: 21pt; line-height: 150%; text-align: justify"><span lang="EN-US" style="color: black; mso-bidi-font-family: arial">values.push_back(2);<o:p></o:p></span></p> <p style="text-justify: inter-ideograph; background: white; margin: 0cm 0cm 9pt; word-break: break-all; text-indent: 21pt; line-height: 150%; text-align: justify"><span lang="EN-US" style="color: black; mso-bidi-font-family: arial">values.push_back(3);<o:p></o:p></span></p> <p style="text-justify: inter-ideograph; background: white; margin: 0cm 0cm 9pt; word-break: break-all; text-indent: 21pt; line-height: 150%; text-align: justify"><span lang="EN-US" style="color: black; mso-bidi-font-family: arial">values.erase(values.begin() + 1);<o:p></o:p></span></p> <p style="text-justify: inter-ideograph; background: white; margin: 0cm 0cm 9pt; word-break: break-all; text-indent: 21pt; line-height: 150%; text-align: justify"><span style="color: black; mso-bidi-font-family: arial">乍看之下<span lang="EN-US">,</span>这几行简单的代码没什么 问题<span lang="EN-US">. </span>实际执行起来<span lang="EN-US">, </span>还是没什么问题<span lang="EN-US"> , </span>但却有一个陷阱<span lang="EN-US">. </span>由于例子里面用的是<span lang="EN-US">int</span>的<span lang="EN-US">vector,</span>所以这样做没有任何问题<span lang="EN-US">, </span>但<span lang="EN-US">,</span>假如不是一个<span lang="EN-US">int, </span>而是一个类<span lang="EN-US">,</span>一个结构体<span lang="EN-US">,</span>类或结构体里面还有指针<span lang="EN-US">, </span>那就很可能出问题了<span lang="EN-US">. why?<o:p></o:p></span></span></p> <p style="text-justify: inter-ideograph; background: white; margin: 0cm 0cm 9pt; word-break: break-all; text-indent: 21pt; line-height: 150%; text-align: justify"><span style="color: black; mso-bidi-font-family: arial">因为<span lang="EN-US">vector</span>不象<span lang="EN-US">list,vector</span>始终要保持一个完整的内存结构<span lang="EN-US">(</span>因为就是一个数组<span lang="EN-US">),</span>这样才可以让<span lang="EN-US">values[1]</span>这样的方式正确运行<span lang="EN-US">. </span>但是<span lang="EN-US">,</span>如果要在<span lang="EN-US">vector</span>中间删掉一个成员的话<span lang="EN-US">,vector</span>是这样做的<span lang="EN-US">, </span>先把该成员后面的一个成员<span lang="EN-US">,</span>一直到最后一个成员往前一位置拷贝<span lang="EN-US">,</span>这样需要删除的成员已经被后面的覆盖了<span lang="EN-US">, </span>然后再删除最后一个成员<span lang="EN-US">,</span>这样<span lang="EN-US">,vector</span>又能保持一段完整的内存结构了<span lang="EN-US">.&nbsp; </span>注意<span lang="EN-US">,</span>因为最后一个成员会被删除<span lang="EN-US">,</span>而如果这个成员里面有一个成员变量是指针<span lang="EN-US">, </span>那析构函数很有可能会把这个指针指向的地方释放掉<span lang="EN-US">!&nbsp; </span>这样<span lang="EN-US">,</span>即使最后一个成员被复制了一份<span lang="EN-US">&nbsp;</span>到倒数第<span lang="EN-US">2</span>的位置<span lang="EN-US">,</span>也因为在他本身被删除的时候<span lang="EN-US">,</span>把倒数第<span lang="EN-US">2</span>个<span lang="EN-US">(</span>也就是它的复制<span lang="EN-US">) </span>的指针成员所指向的地方给释放了<span lang="EN-US">! </span>如图：<span lang="EN-US"><o:p></o:p></span></span></p> <p style="text-justify: inter-ideograph; background: white; margin: 0cm 0cm 0pt; word-break: break-all; text-indent: 21pt; line-height: 150%; text-align: justify"><span lang="EN-US" style="color: black; mso-bidi-font-family: arial">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="apple-converted-space">&nbsp;</span><a href="http://www.alisdn.com/wordpress/wp-content/uploads/2009/04/1.bmp"><span style="color: #0054b3; text-decoration: none; text-underline: none"><span style="mso-ignore: vglayout"><img class="alignnone size-full wp-image-1468" title="clip_image002" style="border-right: 0px; padding-right: 0px; border-top: 0px; display: inline; padding-left: 0px; padding-bottom: 0px; border-left: 0px; padding-top: 0px; border-bottom: 0px; font-family: arial, helvetica, sans-serif; oldpaddingtop: 0px; oldbordertopwidth: ; oldpaddingbottom: 0px; oldborderbottomwidth: ; oldpaddingright: 0px; oldborderrightwidth: ; oldpaddingleft: 0px; oldborderleftwidth: " height="206" alt="clip_image002" src="http://www.cppblog.com/images/cppblog_com/woaidongmao/WindowsLiveWriter/stdvector_13DCB/clip_image002_0faed496-68b4-4907-a855-209a8dfc2c1e.jpg" width="322" border="0" v:shapes="_x0000_i1025" mergenum="0"></span></span></a><o:p></o:p></span></p> <p style="text-justify: inter-ideograph; background: white; margin: 0cm 0cm 9pt; word-break: break-all; text-indent: 21pt; line-height: 150%; text-align: justify"><span style="color: black; mso-bidi-font-family: arial">解决的办法也很简单<span lang="EN-US">, </span>最少有<span lang="EN-US">2</span>种<span lang="EN-US">. 1,&nbsp; </span>增加作为<span lang="EN-US">vector</span>类型的类的拷贝构造函数<span lang="EN-US">, </span>因为<span lang="EN-US">vector</span>在<span lang="EN-US">erase</span>的时候会发生一次拷贝<span lang="EN-US">,</span>让拷贝构造函数不单单是复制指针<span lang="EN-US">,</span>还把指针所指向的内容给拷贝一份<span lang="EN-US">,</span>这样就不会导致被最后一个成员释放的时候一起释放掉了<span lang="EN-US">. 2, </span>如果有引用记数的话<span lang="EN-US">,</span>如智能指针<span lang="EN-US">, </span>就不会被释放掉了。不过如果一般编码里面不需要用到引用记数的话<span lang="EN-US">,</span>还是方法<span lang="EN-US">1</span>比较简便<span lang="EN-US"><o:p></o:p></span></span></p> <p class="MsoNormal" style="line-height: 150%"><span lang="EN-US" style="font-size: 12pt; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial"><o:p>&nbsp;</o:p></span></p><img src ="http://www.cppblog.com/woaidongmao/aggbug/95146.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/woaidongmao/" target="_blank">肥仔</a> 2009-09-02 22:36 <a href="http://www.cppblog.com/woaidongmao/archive/2009/09/02/95146.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>关于STL容器存储对象的问题</title><link>http://www.cppblog.com/woaidongmao/archive/2009/09/02/95144.html</link><dc:creator>肥仔</dc:creator><author>肥仔</author><pubDate>Wed, 02 Sep 2009 14:23:00 GMT</pubDate><guid>http://www.cppblog.com/woaidongmao/archive/2009/09/02/95144.html</guid><wfw:comment>http://www.cppblog.com/woaidongmao/comments/95144.html</wfw:comment><comments>http://www.cppblog.com/woaidongmao/archive/2009/09/02/95144.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/woaidongmao/comments/commentRss/95144.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/woaidongmao/services/trackbacks/95144.html</trackback:ping><description><![CDATA[<p><font size="4">请问如果我在STL容器存储的是对象，那么我在调用clear()或eara()的时候，会自动释放这个对象的内存空间吗？会执行该对象的析够函数吗？</font></p> <p><font size="4">=======================</font></p> <p><font size="4">会，析构函数也会自动调用。&nbsp;&nbsp; <br>&nbsp; 但如果存储的是对象的指针，外部对象如果是在堆上分配的，需要我们自已delete</font>  <p><font size="4">=======================</font>  <p><font size="4">STL的容器是基于<font color="#ff0000">by&nbsp;&nbsp; value语意的。当你把一个元素放入容器中，在容器中存放的实际上是这个元素的一个副本（这就是为什么STL容器要求元素<strong><u>必须可以拷贝构造和赋值</u></strong>），</font>副本所占的内存是STL容器自己分配的，<font color="#ff0000">所以它会自己回收这些内存，同时调用元素的析构函数。</font>&nbsp;&nbsp; <br>&nbsp; 但是如果你把指针放到容器中，clear的时候容器只负责回收指针本身所占的内存，至于指针所指向的东西，它是不管。</font></p><img src ="http://www.cppblog.com/woaidongmao/aggbug/95144.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/woaidongmao/" target="_blank">肥仔</a> 2009-09-02 22:23 <a href="http://www.cppblog.com/woaidongmao/archive/2009/09/02/95144.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>STL 4： STL之容器：选择时机，删除元素，迭代器失效</title><link>http://www.cppblog.com/woaidongmao/archive/2009/08/31/94925.html</link><dc:creator>肥仔</dc:creator><author>肥仔</author><pubDate>Mon, 31 Aug 2009 15:08:00 GMT</pubDate><guid>http://www.cppblog.com/woaidongmao/archive/2009/08/31/94925.html</guid><wfw:comment>http://www.cppblog.com/woaidongmao/comments/94925.html</wfw:comment><comments>http://www.cppblog.com/woaidongmao/archive/2009/08/31/94925.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/woaidongmao/comments/commentRss/94925.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/woaidongmao/services/trackbacks/94925.html</trackback:ping><description><![CDATA[<p class="MsoNormal" style="background: white; word-break: break-all; line-height: 150%; text-align: left; mso-pagination: widow-orphan" align="left"><span lang="EN-US" style="font-size: 12pt; color: black; line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">&nbsp; </span><span style="font-size: 12pt; color: black; line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">一<span lang="EN-US">. </span>种类：<span lang="EN-US"><?xml:namespace prefix = o /><o:p></o:p></span></span></p> <p class="MsoNormal" style="background: white; margin-left: 32.25pt; layout-grid-mode: char; word-break: break-all; text-indent: -18pt; line-height: 150%; text-align: left; mso-pagination: widow-orphan; mso-list: l0 level1 lfo1; tab-stops: list 36.0pt" align="left"><span lang="EN-US" style="font-size: 10pt; color: black; line-height: 150%; font-family: symbol; mso-bidi-font-family: symbol; mso-font-kerning: 0pt; mso-bidi-font-size: 12.0pt; mso-fareast-font-family: symbol"><span style="mso-list: ignore">·<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span><b><span style="font-size: 12pt; color: black; line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">标准<span lang="EN-US">STL</span>序列容器</span></b><span style="font-size: 12pt; color: black; line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">：<span lang="EN-US">vector</span>、<span lang="EN-US">string</span>、<span lang="EN-US">deque</span>和<span lang="EN-US">list</span>。 <span lang="EN-US"><o:p></o:p></span></span></p> <p class="MsoNormal" style="background: white; margin-left: 32.25pt; layout-grid-mode: char; word-break: break-all; text-indent: -18pt; line-height: 150%; text-align: left; mso-pagination: widow-orphan; mso-list: l0 level1 lfo1; tab-stops: list 36.0pt" align="left"><span lang="EN-US" style="font-size: 10pt; color: black; line-height: 150%; font-family: symbol; mso-bidi-font-family: symbol; mso-font-kerning: 0pt; mso-bidi-font-size: 12.0pt; mso-fareast-font-family: symbol"><span style="mso-list: ignore">·<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span><b><span style="font-size: 12pt; color: black; line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">标准<span lang="EN-US">STL</span>关联容器</span></b><span style="font-size: 12pt; color: black; line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">：<span lang="EN-US">set</span>、<span lang="EN-US">multiset</span>、<span lang="EN-US">map</span>和<span lang="EN-US">multimap</span>。 <span lang="EN-US"><o:p></o:p></span></span></p> <p class="MsoNormal" style="background: white; margin-left: 32.25pt; layout-grid-mode: char; word-break: break-all; text-indent: -18pt; line-height: 150%; text-align: left; mso-pagination: widow-orphan; mso-list: l0 level1 lfo1; tab-stops: list 36.0pt" align="left"><span lang="EN-US" style="font-size: 10pt; color: black; line-height: 150%; font-family: symbol; mso-bidi-font-family: symbol; mso-font-kerning: 0pt; mso-bidi-font-size: 12.0pt; mso-fareast-font-family: symbol"><span style="mso-list: ignore">·<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span><b><span style="font-size: 12pt; color: black; line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">非标准序列容器</span></b><span lang="EN-US" style="font-size: 12pt; color: black; line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">slist</span><span style="font-size: 12pt; color: black; line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">和<span lang="EN-US">rope</span>。<span lang="EN-US">slist</span>是一个单向链表，<span lang="EN-US">rope</span>本质上是一个重型字符串 <span lang="EN-US"><o:p></o:p></span></span></p> <p class="MsoNormal" style="background: white; margin-left: 32.25pt; layout-grid-mode: char; word-break: break-all; text-indent: -18pt; line-height: 150%; text-align: left; mso-pagination: widow-orphan; mso-list: l0 level1 lfo1; tab-stops: list 36.0pt" align="left"><span lang="EN-US" style="font-size: 10pt; color: black; line-height: 150%; font-family: symbol; mso-bidi-font-family: symbol; mso-font-kerning: 0pt; mso-bidi-font-size: 12.0pt; mso-fareast-font-family: symbol"><span style="mso-list: ignore">·<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span><b><span style="font-size: 12pt; color: black; line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">非标准关联容器</span></b><span lang="EN-US" style="font-size: 12pt; color: black; line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">hash_set</span><span style="font-size: 12pt; color: black; line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">、<span lang="EN-US">hash_multiset</span>、<span lang="EN-US">hash_map</span>和<span lang="EN-US">hash_multimap</span>。 <span lang="EN-US"><o:p></o:p></span></span></p> <p class="MsoNormal" style="background: white; margin-left: 32.25pt; layout-grid-mode: char; word-break: break-all; text-indent: -18pt; line-height: 150%; text-align: left; mso-pagination: widow-orphan; mso-list: l0 level1 lfo1; tab-stops: list 36.0pt" align="left"><span lang="EN-US" style="font-size: 10pt; color: black; line-height: 150%; font-family: symbol; mso-bidi-font-family: symbol; mso-font-kerning: 0pt; mso-bidi-font-size: 12.0pt; mso-fareast-font-family: symbol"><span style="mso-list: ignore">·<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span><span style="font-size: 12pt; color: black; line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">几种<b>标准非<span lang="EN-US">STL</span>容器</b>，包括数组、<span lang="EN-US">bitset</span>、<span lang="EN-US">valarray</span>、<span lang="EN-US">stack</span>、<span lang="EN-US">queue</span>和<span lang="EN-US">priority_queue <o:p></o:p></span></span></p> <p class="MsoNormal" style="background: white; layout-grid-mode: char; word-break: break-all; line-height: 150%; text-align: left; mso-pagination: widow-orphan" align="left"><span style="font-size: 12pt; background: red; color: black; line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">值得注意的是，数组可以和<span lang="EN-US">STL</span>算法配合，因为指针可以当作数组的迭代器使用</span><span style="font-size: 12pt; background: white; color: black; line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">。</span><span lang="EN-US" style="font-size: 12pt; color: black; line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><o:p></o:p></span></p> <p class="MsoNormal" style="background: white; layout-grid-mode: char; word-break: break-all; line-height: 150%; text-align: left; mso-pagination: widow-orphan" align="left"><span lang="EN-US" style="font-size: 12pt; background: white; color: black; line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">&nbsp; </span><span style="font-size: 12pt; background: white; color: black; line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">二<span lang="EN-US">.</span>删除元素 <span lang="EN-US"><o:p></o:p></span></span></p> <p class="MsoNormal" style="background: white; layout-grid-mode: char; word-break: break-all; line-height: 150%; text-align: left; mso-pagination: widow-orphan" align="left"><span style="font-size: 12pt; background: white; color: black; line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">如果想删除东西，记住<span lang="EN-US">remove</span>算法后，要加上<span lang="EN-US">erase<o:p></o:p></span></span></p> <p class="MsoNormal" style="background: white; layout-grid-mode: char; word-break: break-all; line-height: 150%; text-align: left; mso-pagination: widow-orphan" align="left"><span style="font-size: 12pt; background: white; color: black; line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">所谓删除算法，最终还是要调用成员函数去删除某个元素，但是因为<span lang="EN-US">remove</span>并不知道它现在作用于哪个容器，所以<span lang="EN-US">remove</span>算法不可能真的删除一个元素<span lang="EN-US"><o:p></o:p></span></span></p> <p class="MsoNormal" style="background: white; layout-grid-mode: char; word-break: break-all; line-height: 150%; text-align: left; mso-pagination: widow-orphan" align="left"><span lang="EN-US" style="font-size: 12pt; background: white; color: black; line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">1.Vector<o:p></o:p></span></p> <p class="MsoNormal" style="background: white; layout-grid-mode: char; word-break: break-all; line-height: 150%; text-align: left; mso-pagination: widow-orphan" align="left"><span lang="EN-US" style="font-size: 12pt; background: white; color: black; line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">&nbsp;<o:p></o:p></span></p> <p class="MsoNormal" style="background: white; layout-grid-mode: char; word-break: break-all; line-height: 150%; text-align: left; mso-pagination: widow-orphan" align="left"><span lang="EN-US" style="font-size: 12pt; background: white; color: black; line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">vector&lt;int&gt; v;&nbsp;&nbsp; <o:p></o:p></span></p> <p class="MsoNormal" style="background: white; layout-grid-mode: char; word-break: break-all; line-height: 150%; text-align: left; mso-pagination: widow-orphan" align="left"><span lang="EN-US" style="font-size: 12pt; background: white; color: black; line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">v.reserve(10);&nbsp;&nbsp; <o:p></o:p></span></p> <p class="MsoNormal" style="background: white; layout-grid-mode: char; word-break: break-all; line-height: 150%; text-align: left; mso-pagination: widow-orphan" align="left"><span lang="EN-US" style="font-size: 12pt; background: white; color: black; line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">for (int i = 1; i &lt;= 10; ++i) {<o:p></o:p></span></p> <p class="MsoNormal" style="background: white; layout-grid-mode: char; word-break: break-all; line-height: 150%; text-align: left; mso-pagination: widow-orphan" align="left"><span lang="EN-US" style="font-size: 12pt; background: white; color: black; line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"> v.push_back(i);<o:p></o:p></span></p> <p class="MsoNormal" style="background: white; layout-grid-mode: char; word-break: break-all; line-height: 150%; text-align: left; mso-pagination: widow-orphan" align="left"><span lang="EN-US" style="font-size: 12pt; background: white; color: black; line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">}<o:p></o:p></span></p> <p class="MsoNormal" style="background: white; layout-grid-mode: char; word-break: break-all; line-height: 150%; text-align: left; mso-pagination: widow-orphan" align="left"><span lang="EN-US" style="font-size: 12pt; background: white; color: black; line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">cout &lt;&lt; v.size();&nbsp;&nbsp; // 10<o:p></o:p></span></p> <p class="MsoNormal" style="background: white; layout-grid-mode: char; word-break: break-all; line-height: 150%; text-align: left; mso-pagination: widow-orphan" align="left"><span lang="EN-US" style="font-size: 12pt; background: white; color: black; line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">v[3] = v[5] = v[9] = 99; <o:p></o:p></span></p> <p class="MsoNormal" style="background: white; layout-grid-mode: char; word-break: break-all; line-height: 150%; text-align: left; mso-pagination: widow-orphan" align="left"><span lang="EN-US" style="font-size: 12pt; background: white; color: black; line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">remove(v.begin(), v.end(), 99); <o:p></o:p></span></p> <p class="MsoNormal" style="background: white; layout-grid-mode: char; word-break: break-all; line-height: 150%; text-align: left; mso-pagination: widow-orphan" align="left"><span lang="EN-US" style="font-size: 12pt; background: white; color: black; line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">//v.erase(remove(v.begin(),v.end(),99),v.end());<o:p></o:p></span></p> <p class="MsoNormal" style="background: white; layout-grid-mode: char; word-break: break-all; line-height: 150%; text-align: left; mso-pagination: widow-orphan" align="left"><span lang="EN-US" style="font-size: 12pt; background: white; color: black; line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">cout &lt;&lt; v.size();&nbsp;&nbsp; // 10</span><span style="font-size: 12pt; background: white; color: black; line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">！<span lang="EN-US"><o:p></o:p></span></span></p> <p class="MsoNormal" style="background: white; layout-grid-mode: char; word-break: break-all; line-height: 150%; text-align: left; mso-pagination: widow-orphan" align="left"><span lang="EN-US" style="font-size: 12pt; background: white; color: black; line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">2. list<o:p></o:p></span></p> <p class="MsoNormal" style="background: white; layout-grid-mode: char; word-break: break-all; line-height: 150%; text-align: left; mso-pagination: widow-orphan" align="left"><span lang="EN-US" style="font-size: 12pt; background: white; color: black; line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">list&lt;int&gt; listTest;<o:p></o:p></span></p> <p class="MsoNormal" style="background: white; layout-grid-mode: char; word-break: break-all; line-height: 150%; text-align: left; mso-pagination: widow-orphan" align="left"><span lang="EN-US" style="font-size: 12pt; background: white; color: black; line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">listTest.remove(99);//</span><span style="font-size: 12pt; background: white; color: black; line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">这个成员函数将真的删除元素，并且要比<span lang="EN-US">erase+remove</span>高效<span lang="EN-US"><o:p></o:p></span></span></p> <p class="MsoNormal" style="background: white; layout-grid-mode: char; word-break: break-all; line-height: 150%; text-align: left; mso-pagination: widow-orphan" align="left"><span lang="EN-US" style="font-size: 12pt; background: white; color: black; line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">remove</span><span style="font-size: 12pt; background: white; color: black; line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">和<span lang="EN-US">remove_if</span>之间的十分相似。但<span lang="EN-US">unique</span>行为也像<span lang="EN-US">remove</span>。它用来从一个区间删除东西（邻近的重复值）而不用访问持有区间元素的容器。如果你真的要从容器中删除元素，你也必须成对调用<span lang="EN-US">unique</span>和<span lang="EN-US">erase</span>，<span lang="EN-US">unique</span>在<span lang="EN-US">list</span>中也类似于<span lang="EN-US">remove</span>。正像<span lang="EN-US">list::remove</span>真的删除东西（而且比<span lang="EN-US">erase-remove</span>惯用法高效得多）。<span lang="EN-US">list::unique</span>也真的删除邻近的重复值（也比<span lang="EN-US">erase-unique</span>高效）。<span lang="EN-US"><o:p></o:p></span></span></p> <p class="MsoNormal" style="background: white; layout-grid-mode: char; word-break: break-all; line-height: 150%; text-align: left; mso-pagination: widow-orphan" align="left"><span lang="EN-US" style="font-size: 12pt; color: black; line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">&nbsp;<o:p></o:p></span></p> <p class="MsoNormal" style="background: white; layout-grid-mode: char; word-break: break-all; line-height: 150%; text-align: left; mso-pagination: widow-orphan" align="left"><span style="font-size: 12pt; color: black; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial; mso-font-kerning: 0pt">三 迭代器失效：</span><span lang="EN-US" style="font-size: 12pt; color: black; line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><o:p></o:p></span></p> <p class="MsoNormal" style="background: white; layout-grid-mode: char; word-break: break-all; line-height: 150%; text-align: left; mso-pagination: widow-orphan" align="left"><span lang="EN-US" style="font-size: 12pt; color: black; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial; mso-font-kerning: 0pt">&nbsp; <o:p></o:p></span></p> <p class="MsoNormal" style="background: white; layout-grid-mode: char; word-break: break-all; line-height: 150%; text-align: left; mso-pagination: widow-orphan" align="left"><span style="font-size: 12pt; color: black; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial; mso-font-kerning: 0pt">一个网友提的问题：<span lang="EN-US"><o:p></o:p></span></span></p> <p class="MsoNormal" style="background: white; layout-grid-mode: char; word-break: break-all; line-height: 150%; text-align: left; mso-pagination: widow-orphan" align="left"><span lang="EN-US" style="font-size: 12pt; color: black; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial; mso-font-kerning: 0pt">void&nbsp;&nbsp; main() <br>{ <br>vector &lt;string&gt; vcs; <br>vcs.push_back( "this&nbsp;&nbsp; is&nbsp;&nbsp; A "); <br>vector &lt;string&nbsp;&nbsp; &gt; ::iterator&nbsp;&nbsp; it=vcs.begin(); <br>int&nbsp;&nbsp; i=9; <br>for(;it!=vcs.end();++it) <br>{ <br>cout &lt; &lt; "caplity&nbsp;&nbsp; of&nbsp;&nbsp; vector&nbsp;&nbsp; is&nbsp;&nbsp; :&nbsp;&nbsp; " &lt; &lt;vcs.size() &lt; &lt;endl; <br><br>cout &lt; &lt; "---&gt; " &lt; &lt;*it &lt; &lt;endl;&nbsp;&nbsp; //</span><span style="font-size: 12pt; color: black; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial; mso-font-kerning: 0pt">去掉此句会有一个超过<span lang="EN-US">vector <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //</span>大小的循环，高手能解释一下为什么<span lang="EN-US">? <br>if(i==9) <br>{ <br>vcs.push_back( "this&nbsp;&nbsp; is&nbsp;&nbsp; BBBBB "); <br>cout &lt; &lt; "vcs.push! " &lt; &lt;endl; <br>} <br>i=8; <br>} <br>}<o:p></o:p></span></span></p> <p class="MsoNormal" style="background: white; layout-grid-mode: char; word-break: break-all; line-height: 150%; text-align: left; mso-pagination: widow-orphan" align="left"><span style="font-size: 12pt; background: red; color: black; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial; mso-font-kerning: 0pt">典型的迭代器失效<span lang="EN-US">....</span></span><span lang="EN-US" style="font-size: 12pt; color: black; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial; mso-font-kerning: 0pt"><o:p></o:p></span></p> <p class="MsoNormal" style="background: white; layout-grid-mode: char; word-break: break-all; line-height: 150%; text-align: left; mso-pagination: widow-orphan" align="left"><span lang="EN-US" style="font-size: 12pt; color: black; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial; mso-font-kerning: 0pt">&nbsp; <o:p></o:p></span></p> <p class="MsoNormal" style="background: white; layout-grid-mode: char; word-break: break-all; line-height: 150%; text-align: left; mso-pagination: widow-orphan" align="left"><span lang="EN-US" style="font-size: 12pt; background: red; color: black; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial; mso-font-kerning: 0pt">vector</span><span style="font-size: 12pt; color: black; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial; mso-font-kerning: 0pt">：<span lang="EN-US"><br>1.</span>当插入（<span lang="EN-US">push_back</span>）一个元素后，<span lang="EN-US">end</span>操作返回的迭代器肯定失效。<span lang="EN-US"><br>2.</span>当插入<span lang="EN-US">(push_back)</span>一个元素后，<span lang="EN-US">capacity</span>返回值与没有插入元素之前相比有改变，则需要重新加载整个容器，此时<span lang="EN-US">first</span>和<span lang="EN-US">end</span>操作返回的迭代器都会失效。<span lang="EN-US"><br>3.</span>当进行删除操作（<span lang="EN-US">erase</span>，<span lang="EN-US">pop_back</span>）后，指向删除点的迭代器全部失效；指向删除点后面的元素的迭代器也将全部失效。<span lang="EN-US"><o:p></o:p></span></span></p> <p class="MsoNormal" style="background: white; layout-grid-mode: char; word-break: break-all; line-height: 150%; text-align: left; mso-pagination: widow-orphan" align="left"><span lang="EN-US" style="font-size: 12pt; background: red; color: black; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial; mso-font-kerning: 0pt">deque</span><span style="font-size: 12pt; color: black; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial; mso-font-kerning: 0pt">迭代器的失效情况：<span lang="EN-US"><br>1.</span>在<span lang="EN-US">deque</span>容器首部或者尾部插入元素不会使得任何迭代器失效。<span lang="EN-US"><br>2.</span>在其首部或尾部删除元素则只会使指向被删除元素的迭代器失效。<span lang="EN-US"><br>3.</span>在<span lang="EN-US">deque</span>容器的任何其他位置的插入和删除操作将使指向该容器元素的所有迭代器失效。<span lang="EN-US"><o:p></o:p></span></span></p> <p class="MsoNormal" style="background: white; layout-grid-mode: char; word-break: break-all; line-height: 150%; text-align: left; mso-pagination: widow-orphan" align="left"><span lang="EN-US" style="font-size: 12pt; background: red; color: black; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial; mso-font-kerning: 0pt">List/set/map</span><span lang="EN-US" style="font-size: 12pt; color: black; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial; mso-font-kerning: 0pt"><o:p></o:p></span></p> <p class="MsoNormal" style="background: white; layout-grid-mode: char; word-break: break-all; line-height: 150%; text-align: left; mso-pagination: widow-orphan" align="left"><span lang="EN-US" style="font-size: 12pt; color: black; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial; mso-font-kerning: 0pt">1.</span><span style="font-size: 12pt; color: black; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial; mso-font-kerning: 0pt">删除时，指向该删除节点的迭代器失效<span lang="EN-US"><o:p></o:p></span></span></p> <p class="MsoNormal" style="background: white; layout-grid-mode: char; word-break: break-all; line-height: 150%; text-align: left; mso-pagination: widow-orphan" align="left"><span lang="EN-US" style="font-size: 12pt; color: black; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial; mso-font-kerning: 0pt">list&lt;int&gt; intList; <br>list&lt;int&gt;::iterator it = intList.begin(); <br>while(it != intList.end()) <br>{ <br>it = intList.erase(it); <br></span><span style="font-size: 12pt; color: black; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial; mso-font-kerning: 0pt">……<span lang="EN-US"> <br>}<o:p></o:p></span></span></p> <p class="MsoNormal" style="background: white; layout-grid-mode: char; word-break: break-all; line-height: 150%; text-align: left; mso-pagination: widow-orphan" align="left"><span style="font-size: 12pt; color: black; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial; mso-font-kerning: 0pt">四<span lang="EN-US">.</span>选择时机<span lang="EN-US">&lt;</span>转<span lang="EN-US">&gt;--</span>总结各种容器特点<span lang="EN-US"><o:p></o:p></span></span></p> <p class="MsoNormal" style="background: white; layout-grid-mode: char; word-break: break-all; line-height: 150%; text-align: left; mso-pagination: widow-orphan" align="left"><span lang="EN-US" style="font-size: 12pt; color: black; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial; mso-font-kerning: 0pt">(1) vector<br></span><span style="font-size: 12pt; color: black; line-height: 150%; font-family: 宋体; mso-bidi-font-family: arial; mso-font-kerning: 0pt">内部数据结构：数组。<span lang="EN-US"><br></span>随机访问每个元素，所需要的时间为常量。<span lang="EN-US"><br></span>在末尾增加或删除元素所需时间与元素数目无关，在中间或开头增加或删除元素所需时间随元素数目呈线性变化。<span lang="EN-US"><br></span>可动态增加或减少元素，内存管理自动完成，但程序员可以使用<span lang="EN-US">reserve()</span>成员函数来管理内存。<span lang="EN-US"><br>vector</span>的迭代器在内存重新分配时将失效（它所指向的元素在该操作的前后不再相同）。当把超过<span lang="EN-US">capacity()-size()</span>个元素插入<span lang="EN-US">vector</span>中时，内存会重新分配，所有的迭代器都将失效；否则，指向当前元素以后的任何元素的迭代器都将失效。当删除元素时，指向被删除元素以后的任何元素的迭代器都将失效。<span lang="EN-US"><br><br>(2)deque<br></span>内部数据结构：数组。<span lang="EN-US"><br></span>随机访问每个元素，所需要的时间为常量。<span lang="EN-US"><br></span>在开头和末尾增加元素所需时间与元素数目无关，在中间增加或删除元素所需时间随元素数目呈线性变化。<span lang="EN-US"><br></span>可动态增加或减少元素，内存管理自动完成，不提供用于内存管理的成员函数。<span lang="EN-US"><br></span>增加任何元素都将使<span lang="EN-US">deque</span>的迭代器失效。在<span lang="EN-US">deque</span>的中间删除元素将使迭代器失效。在<span lang="EN-US">deque</span>的头或尾删除元素时，只有指向该元素的迭代器失效。<span lang="EN-US"><br><br>(3)list<br></span>内部数据结构：双向环状链表。<span lang="EN-US"><br></span>不能随机访问一个元素。<span lang="EN-US"><br></span>可双向遍历。<span lang="EN-US"><br></span>在开头、末尾和中间任何地方增加或删除元素所需时间都为常量。<span lang="EN-US"><br></span>可动态增加或减少元素，内存管理自动完成。<span lang="EN-US"><br></span>增加任何元素都不会使迭代器失效。删除元素时，除了指向当前被删除元素的迭代器外，其它迭代器都不会失效。<span lang="EN-US"><br><br>(4)slist<br></span>内部数据结构：单向链表。<span lang="EN-US"><br></span>不可双向遍历，只能从前到后地遍历。<span lang="EN-US"><br></span>其它的特性同<span lang="EN-US">list</span>相似。<span lang="EN-US"><br><br>(5)stack<br></span>适配器，它可以将任意类型的序列容器转换为一个堆栈，一般使用<span lang="EN-US">deque</span>作为支持的序列容器。<span lang="EN-US"><br></span>元素只能后进先出（<span lang="EN-US">LIFO</span>）。<span lang="EN-US"><br></span>不能遍历整个<span lang="EN-US">stack</span>。<span lang="EN-US"><br><br>(6)queue<br></span>适配器，它可以将任意类型的序列容器转换为一个队列，一般使用<span lang="EN-US">deque</span>作为支持的序列容器。<span lang="EN-US"><br></span>元素只能先进先出（<span lang="EN-US">FIFO</span>）。<span lang="EN-US"><br></span>不能遍历整个<span lang="EN-US">queue</span>。<span lang="EN-US"><br><br>(7)priority_queue<br></span>适配器，它可以将任意类型的序列容器转换为一个优先级队列，一般使用<span lang="EN-US">vector</span>作为底层存储方式。<span lang="EN-US"><br></span>只能访问第一个元素，不能遍历整个<span lang="EN-US">priority_queue</span>。<span lang="EN-US"><br></span>第一个元素始终是优先级最高的一个元素。<span lang="EN-US"><br><br>(8)set<br></span>键和值相等。<span lang="EN-US"><br></span>键唯一。<span lang="EN-US"><br></span>元素默认按升序排列。<span lang="EN-US"><br></span>如果迭代器所指向的元素被删除，则该迭代器失效。其它任何增加、删除元素的操作都不会使迭代器失效。<span lang="EN-US"><br><br>(9)multiset<br></span>键可以不唯一。<span lang="EN-US"><br></span>其它特点与<span lang="EN-US">set</span>相同。<span lang="EN-US"><br><br>(10)hash_set<br></span>与<span lang="EN-US">set</span>相比较，它里面的元素不一定是经过排序的，而是按照所用的<span lang="EN-US">hash</span>函数分派的，它能提供更快的搜索速度（当然跟<span lang="EN-US">hash</span>函数有关）。<span lang="EN-US"><br></span>其它特点与<span lang="EN-US">set</span>相同。<span lang="EN-US"><br><br>(11)hash_multiset<br></span>键可以不唯一。<span lang="EN-US"><br></span>其它特点与<span lang="EN-US">hash_set</span>相同。<span lang="EN-US"><br><br>(12)map<br></span>键唯一。<span lang="EN-US"><br></span>元素默认按键的升序排列。<span lang="EN-US"><br></span>如果迭代器所指向的元素被删除，则该迭代器失效。其它任何增加、删除元素的操作都不会使迭代器失效。<span lang="EN-US"><br><br>(13)multimap<br></span>键可以不唯一。<span lang="EN-US"><br></span>其它特点与<span lang="EN-US">map</span>相同。<span lang="EN-US"><br><br>(14)hash_map<br></span>与<span lang="EN-US">map</span>相比较，它里面的元素不一定是按键值排序的，而是按照所用的<span lang="EN-US">hash</span>函数分派的，它能提供更快的搜索速度（当然也跟<span lang="EN-US">hash</span>函数有关）。<span lang="EN-US"><br></span>其它特点与<span lang="EN-US">map</span>相同。<span lang="EN-US"><br><br>(15)hash_multimap<br></span>键可以不唯一。<span lang="EN-US"><br></span>其它特点与<span lang="EN-US">hash_map</span>相同。<span lang="EN-US"><o:p></o:p></span></span></p> <p class="MsoNormal"><span lang="EN-US" style="font-size: 12pt; color: black; font-family: 宋体; mso-bidi-font-family: arial"><o:p>&nbsp;</o:p></span></p> <p class="MsoNormal"><span lang="EN-US" style="font-size: 12pt; color: black; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><o:p>&nbsp;</o:p></span></p><img src ="http://www.cppblog.com/woaidongmao/aggbug/94925.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/woaidongmao/" target="_blank">肥仔</a> 2009-08-31 23:08 <a href="http://www.cppblog.com/woaidongmao/archive/2009/08/31/94925.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>STLPORT的bug</title><link>http://www.cppblog.com/woaidongmao/archive/2009/07/16/90254.html</link><dc:creator>肥仔</dc:creator><author>肥仔</author><pubDate>Thu, 16 Jul 2009 08:52:00 GMT</pubDate><guid>http://www.cppblog.com/woaidongmao/archive/2009/07/16/90254.html</guid><wfw:comment>http://www.cppblog.com/woaidongmao/comments/90254.html</wfw:comment><comments>http://www.cppblog.com/woaidongmao/archive/2009/07/16/90254.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/woaidongmao/comments/commentRss/90254.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/woaidongmao/services/trackbacks/90254.html</trackback:ping><description><![CDATA[<p>当采用静态连接，定义了:,_STLP_USE_STATIC_LIB</p> <p>string的下面红色代码出错，采用动态库，却没有发现这个问题</p> <p>template &lt;bool __threads, int __inst&gt;<br>void* _STLP_CALL<br>__node_alloc&lt;__threads, __inst&gt;::_M_allocate(size_t __n) {<br>&nbsp; void*&nbsp; __r;<br>&nbsp; _Obj * _STLP_VOLATILE * __my_free_list = _S_free_list + _S_FREELIST_INDEX(__n);<br>&nbsp; // #&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ifdef _STLP_THREADS<br>&nbsp; /*REFERENCED*/<br>&nbsp; _Node_Alloc_Lock&lt;__threads, __inst&gt; __lock_instance;<br>&nbsp; // #&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; endif<br>&nbsp; // Acquire the lock here with a constructor call.<br>&nbsp; // This ensures that it is released in exit or during stack<br>&nbsp; // unwinding.<br>&nbsp; if ( (__r&nbsp; = *__my_free_list) != 0 ) {<br><font color="#ff0000">&nbsp;&nbsp;&nbsp; *__my_free_list = ((_Obj*)__r) -&gt; _M_free_list_link;</font><br>&nbsp; } else {<br>&nbsp;&nbsp;&nbsp; __r = _S_refill(__n);<br>&nbsp; }</p> <p>&nbsp;</p> <p>解决办法：</p> <p><font color="#ff0000">使用动态库的STLPORT</font></p><img src ="http://www.cppblog.com/woaidongmao/aggbug/90254.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/woaidongmao/" target="_blank">肥仔</a> 2009-07-16 16:52 <a href="http://www.cppblog.com/woaidongmao/archive/2009/07/16/90254.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>关于stl 迭代器失效</title><link>http://www.cppblog.com/woaidongmao/archive/2009/07/09/89653.html</link><dc:creator>肥仔</dc:creator><author>肥仔</author><pubDate>Thu, 09 Jul 2009 06:48:00 GMT</pubDate><guid>http://www.cppblog.com/woaidongmao/archive/2009/07/09/89653.html</guid><wfw:comment>http://www.cppblog.com/woaidongmao/comments/89653.html</wfw:comment><comments>http://www.cppblog.com/woaidongmao/archive/2009/07/09/89653.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/woaidongmao/comments/commentRss/89653.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/woaidongmao/services/trackbacks/89653.html</trackback:ping><description><![CDATA[<p class="MsoNormal" style="line-height: 150%; text-align: left; mso-pagination: widow-orphan" align="left"><span style="font-size: 12pt; line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">先看两条规制：<span lang="EN-US"><br><br><span style="color: red">1</span></span><span style="color: red">，对于节点式容器<span lang="EN-US">(map, list, set)</span>元素的删除，插入操作会导致指向该元素的迭代器失效，其他元素迭代器不受影响<span lang="EN-US"><br><br>2</span>，对于顺序式容器<span lang="EN-US">(vector)</span>元素的删除、插入操作会导致指向该元素以及后面的元素的迭代器失效</span><span lang="EN-US"><br><br></span>常见的错误代码示例：<span lang="EN-US"><?xml:namespace prefix = o /><o:p></o:p></span></span></p> <p class="MsoNormal" style="background: #eeeeee; word-break: break-all; line-height: 150%; text-align: left; mso-pagination: widow-orphan" align="left"><span lang="EN-US" style="font-size: 12pt; color: teal; line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"> 1</span><span lang="EN-US" style="font-size: 12pt; line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><a href="http://www.cppblog.com/images/cppblog_com/woaidongmao/WindowsLiveWriter/stl_D009/clip_image001_74.gif"><img title="clip_image001" style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" height="16" alt="clip_image001" src="http://www.cppblog.com/images/cppblog_com/woaidongmao/WindowsLiveWriter/stl_D009/clip_image001_thumb_24.gif" width="11" border="0" v:shapes="_x0000_i1025"></a><span style="color: blue">struct</span><span style="color: black"> sMem <br></span><span style="color: teal"> 2</span><span style="border-right: gray 1pt solid; padding-right: 0cm; border-top: gray 1pt solid; display: none; padding-left: 0cm; background: white; padding-bottom: 0cm; border-left: gray 1pt solid; padding-top: 0cm; border-bottom: gray 1pt solid; mso-hide: all; mso-border-alt: solid gray .75pt"><a href="http://www.cppblog.com/images/cppblog_com/woaidongmao/WindowsLiveWriter/stl_D009/clip_image002_42.gif"><img title="clip_image002" style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" height="24" alt="clip_image002" src="http://www.cppblog.com/images/cppblog_com/woaidongmao/WindowsLiveWriter/stl_D009/clip_image002_thumb_12.gif" width="19" border="0" v:shapes="_x0000_i1026"></a></span><span style="color: black">{<br></span><span style="color: teal"> 3</span><span style="color: black"><a href="http://www.cppblog.com/images/cppblog_com/woaidongmao/WindowsLiveWriter/stl_D009/clip_image003_50.gif"><img title="clip_image003" style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" height="16" alt="clip_image003" src="http://www.cppblog.com/images/cppblog_com/woaidongmao/WindowsLiveWriter/stl_D009/clip_image003_thumb_14.gif" width="11" border="0" v:shapes="_x0000_i1027"></a>&nbsp;&nbsp;&nbsp; </span><span style="color: blue">int</span><span style="color: black"> m_i;<br></span><span style="color: teal"> 4</span><span style="color: black"><a href="http://www.cppblog.com/images/cppblog_com/woaidongmao/WindowsLiveWriter/stl_D009/clip_image003_52.gif"><img title="clip_image003" style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" height="16" alt="clip_image003" src="http://www.cppblog.com/images/cppblog_com/woaidongmao/WindowsLiveWriter/stl_D009/clip_image003_thumb_15.gif" width="11" border="0" v:shapes="_x0000_i1028"></a>&nbsp;&nbsp;&nbsp; sMem(</span><span style="color: blue">int</span><span style="color: black"> i = 10)<br></span><span style="color: teal"> 5</span><span style="color: black">&nbsp;&nbsp;&nbsp; </span><span style="border-right: gray 1pt solid; padding-right: 0cm; border-top: gray 1pt solid; display: none; padding-left: 0cm; background: white; padding-bottom: 0cm; border-left: gray 1pt solid; padding-top: 0cm; border-bottom: gray 1pt solid; mso-hide: all; mso-border-alt: solid gray .75pt"><a href="http://www.cppblog.com/images/cppblog_com/woaidongmao/WindowsLiveWriter/stl_D009/clip_image002_44.gif"><img title="clip_image002" style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" height="24" alt="clip_image002" src="http://www.cppblog.com/images/cppblog_com/woaidongmao/WindowsLiveWriter/stl_D009/clip_image002_thumb_13.gif" width="19" border="0" v:shapes="_x0000_i1029"></a></span><span style="color: black">{<br></span><span style="color: teal"> 6</span><span style="color: black"><a href="http://www.cppblog.com/images/cppblog_com/woaidongmao/WindowsLiveWriter/stl_D009/clip_image003_54.gif"><img title="clip_image003" style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" height="16" alt="clip_image003" src="http://www.cppblog.com/images/cppblog_com/woaidongmao/WindowsLiveWriter/stl_D009/clip_image003_thumb_16.gif" width="11" border="0" v:shapes="_x0000_i1030"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; m_i = i;<br></span><span style="color: teal"> 7</span><span style="color: black"><a href="http://www.cppblog.com/images/cppblog_com/woaidongmao/WindowsLiveWriter/stl_D009/clip_image004_30.gif"><img title="clip_image004" style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" height="16" alt="clip_image004" src="http://www.cppblog.com/images/cppblog_com/woaidongmao/WindowsLiveWriter/stl_D009/clip_image004_thumb_11.gif" width="11" border="0" v:shapes="_x0000_i1031"></a>&nbsp;&nbsp;&nbsp; }<br></span><span style="color: teal"> 8</span><span style="color: black"><a href="http://www.cppblog.com/images/cppblog_com/woaidongmao/WindowsLiveWriter/stl_D009/clip_image003_56.gif"><img title="clip_image003" style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" height="16" alt="clip_image003" src="http://www.cppblog.com/images/cppblog_com/woaidongmao/WindowsLiveWriter/stl_D009/clip_image003_thumb_17.gif" width="11" border="0" v:shapes="_x0000_i1032"></a><br></span><span style="color: teal"> 9</span><span style="color: black"><a href="http://www.cppblog.com/images/cppblog_com/woaidongmao/WindowsLiveWriter/stl_D009/clip_image003_58.gif"><img title="clip_image003" style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" height="16" alt="clip_image003" src="http://www.cppblog.com/images/cppblog_com/woaidongmao/WindowsLiveWriter/stl_D009/clip_image003_thumb_18.gif" width="11" border="0" v:shapes="_x0000_i1033"></a>&nbsp;&nbsp;&nbsp; </span><span style="color: blue">int</span><span style="color: black"> GetI()<br></span><span style="color: teal">10</span><span style="color: black">&nbsp;&nbsp;&nbsp; </span><span style="border-right: gray 1pt solid; padding-right: 0cm; border-top: gray 1pt solid; display: none; padding-left: 0cm; background: white; padding-bottom: 0cm; border-left: gray 1pt solid; padding-top: 0cm; border-bottom: gray 1pt solid; mso-hide: all; mso-border-alt: solid gray .75pt"><a href="http://www.cppblog.com/images/cppblog_com/woaidongmao/WindowsLiveWriter/stl_D009/clip_image002_46.gif"><img title="clip_image002" style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" height="24" alt="clip_image002" src="http://www.cppblog.com/images/cppblog_com/woaidongmao/WindowsLiveWriter/stl_D009/clip_image002_thumb_14.gif" width="19" border="0" v:shapes="_x0000_i1034"></a></span><span style="color: black">{<br></span><span style="color: teal">11</span><span style="color: black"><a href="http://www.cppblog.com/images/cppblog_com/woaidongmao/WindowsLiveWriter/stl_D009/clip_image003_60.gif"><img title="clip_image003" style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" height="16" alt="clip_image003" src="http://www.cppblog.com/images/cppblog_com/woaidongmao/WindowsLiveWriter/stl_D009/clip_image003_thumb_19.gif" width="11" border="0" v:shapes="_x0000_i1035"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: blue">return</span><span style="color: black"> m_i;<br></span><span style="color: teal">12</span><span style="color: black"><a href="http://www.cppblog.com/images/cppblog_com/woaidongmao/WindowsLiveWriter/stl_D009/clip_image004_32.gif"><img title="clip_image004" style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" height="16" alt="clip_image004" src="http://www.cppblog.com/images/cppblog_com/woaidongmao/WindowsLiveWriter/stl_D009/clip_image004_thumb_12.gif" width="11" border="0" v:shapes="_x0000_i1036"></a>&nbsp;&nbsp;&nbsp; }<br></span><span style="color: teal">13</span><span style="color: black"><a href="http://www.cppblog.com/images/cppblog_com/woaidongmao/WindowsLiveWriter/stl_D009/clip_image005_42.gif"><img title="clip_image005" style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" height="16" alt="clip_image005" src="http://www.cppblog.com/images/cppblog_com/woaidongmao/WindowsLiveWriter/stl_D009/clip_image005_thumb_18.gif" width="11" border="0" v:shapes="_x0000_i1037"></a>};</span><o:p></o:p></span></p> <p class="MsoNormal" style="background: #eeeeee; word-break: break-all; line-height: 150%; text-align: left; mso-pagination: widow-orphan" align="left"><span lang="EN-US" style="font-size: 12pt; color: teal; line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">1</span><span lang="EN-US" style="font-size: 12pt; line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><a href="http://www.cppblog.com/images/cppblog_com/woaidongmao/WindowsLiveWriter/stl_D009/clip_image001_76.gif"><img title="clip_image001" style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" height="16" alt="clip_image001" src="http://www.cppblog.com/images/cppblog_com/woaidongmao/WindowsLiveWriter/stl_D009/clip_image001_thumb_25.gif" width="11" border="0" v:shapes="_x0000_i1038"></a><span style="color: black"><br></span><span style="color: teal">2</span><span style="color: black"><a href="http://www.cppblog.com/images/cppblog_com/woaidongmao/WindowsLiveWriter/stl_D009/clip_image001_78.gif"><img title="clip_image001" style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" height="16" alt="clip_image001" src="http://www.cppblog.com/images/cppblog_com/woaidongmao/WindowsLiveWriter/stl_D009/clip_image001_thumb_26.gif" width="11" border="0" v:shapes="_x0000_i1039"></a>typedef vector&lt;sMem*&gt; sMemList;<br></span><span style="color: teal">3</span><span style="color: black"><a href="http://www.cppblog.com/images/cppblog_com/woaidongmao/WindowsLiveWriter/stl_D009/clip_image001_80.gif"><img title="clip_image001" style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" height="16" alt="clip_image001" src="http://www.cppblog.com/images/cppblog_com/woaidongmao/WindowsLiveWriter/stl_D009/clip_image001_thumb_27.gif" width="11" border="0" v:shapes="_x0000_i1040"></a>typedef vector&lt;sMem*&gt;::iterator sIT;<br></span><span style="color: teal">4</span><span style="color: black"><a href="http://www.cppblog.com/images/cppblog_com/woaidongmao/WindowsLiveWriter/stl_D009/clip_image001_82.gif"><img title="clip_image001" style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" height="16" alt="clip_image001" src="http://www.cppblog.com/images/cppblog_com/woaidongmao/WindowsLiveWriter/stl_D009/clip_image001_thumb_28.gif" width="11" border="0" v:shapes="_x0000_i1041"></a>sMemList MemList;</span><o:p></o:p></span></p> <p class="MsoNormal" style="background: #eeeeee; word-break: break-all; line-height: 150%; text-align: left; mso-pagination: widow-orphan" align="left"><span lang="EN-US" style="font-size: 12pt; color: teal; line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"> 1</span><span lang="EN-US" style="font-size: 12pt; line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><a href="http://www.cppblog.com/images/cppblog_com/woaidongmao/WindowsLiveWriter/stl_D009/clip_image001_84.gif"><img title="clip_image001" style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" height="16" alt="clip_image001" src="http://www.cppblog.com/images/cppblog_com/woaidongmao/WindowsLiveWriter/stl_D009/clip_image001_thumb_29.gif" width="11" border="0" v:shapes="_x0000_i1042"></a><span style="color: black">&nbsp;&nbsp;&nbsp; </span><span style="color: green">// </span></span><span style="font-size: 12pt; color: green; line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">迭代器失效<span lang="EN-US"><br></span></span><span lang="EN-US" style="font-size: 12pt; color: teal; line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"> 2</span><span lang="EN-US" style="font-size: 12pt; color: green; line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><a href="http://www.cppblog.com/images/cppblog_com/woaidongmao/WindowsLiveWriter/stl_D009/clip_image001_86.gif"><img title="clip_image001" style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" height="16" alt="clip_image001" src="http://www.cppblog.com/images/cppblog_com/woaidongmao/WindowsLiveWriter/stl_D009/clip_image001_thumb_30.gif" width="11" border="0" v:shapes="_x0000_i1043"></a></span><span lang="EN-US" style="font-size: 12pt; color: black; line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">&nbsp;&nbsp;&nbsp; </span><span lang="EN-US" style="font-size: 12pt; color: blue; line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">for</span><span lang="EN-US" style="font-size: 12pt; color: black; line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"> (sIT it = MemList.begin(); it != MemList.end(); ++it)<br></span><span lang="EN-US" style="font-size: 12pt; color: teal; line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"> 3</span><span lang="EN-US" style="font-size: 12pt; color: black; line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">&nbsp;&nbsp;&nbsp; </span><span lang="EN-US" style="border-right: gray 1pt solid; padding-right: 0cm; border-top: gray 1pt solid; display: none; padding-left: 0cm; font-size: 12pt; background: white; padding-bottom: 0cm; border-left: gray 1pt solid; line-height: 150%; padding-top: 0cm; border-bottom: gray 1pt solid; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt; mso-hide: all; mso-border-alt: solid gray .75pt"><a href="http://www.cppblog.com/images/cppblog_com/woaidongmao/WindowsLiveWriter/stl_D009/clip_image002_48.gif"><img title="clip_image002" style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" height="24" alt="clip_image002" src="http://www.cppblog.com/images/cppblog_com/woaidongmao/WindowsLiveWriter/stl_D009/clip_image002_thumb_15.gif" width="19" border="0" v:shapes="_x0000_i1044"></a></span><span lang="EN-US" style="font-size: 12pt; color: black; line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">{<br></span><span lang="EN-US" style="font-size: 12pt; color: teal; line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"> 4</span><span lang="EN-US" style="font-size: 12pt; color: black; line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><a href="http://www.cppblog.com/images/cppblog_com/woaidongmao/WindowsLiveWriter/stl_D009/clip_image003_62.gif"><img title="clip_image003" style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" height="16" alt="clip_image003" src="http://www.cppblog.com/images/cppblog_com/woaidongmao/WindowsLiveWriter/stl_D009/clip_image003_thumb_20.gif" width="11" border="0" v:shapes="_x0000_i1045"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span lang="EN-US" style="font-size: 12pt; color: blue; line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">if</span><span lang="EN-US" style="font-size: 12pt; color: black; line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"> ((*it)-&gt;GetI() == 10)<br></span><span lang="EN-US" style="font-size: 12pt; color: teal; line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"> 5</span><span lang="EN-US" style="font-size: 12pt; color: black; line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><a href="http://www.cppblog.com/images/cppblog_com/woaidongmao/WindowsLiveWriter/stl_D009/clip_image003_64.gif"><img title="clip_image003" style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" height="16" alt="clip_image003" src="http://www.cppblog.com/images/cppblog_com/woaidongmao/WindowsLiveWriter/stl_D009/clip_image003_thumb_21.gif" width="11" border="0" v:shapes="_x0000_i1046"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MemList.erase(it);<br></span><span lang="EN-US" style="font-size: 12pt; color: teal; line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"> 6</span><span lang="EN-US" style="font-size: 12pt; color: black; line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><a href="http://www.cppblog.com/images/cppblog_com/woaidongmao/WindowsLiveWriter/stl_D009/clip_image003_66.gif"><img title="clip_image003" style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" height="16" alt="clip_image003" src="http://www.cppblog.com/images/cppblog_com/woaidongmao/WindowsLiveWriter/stl_D009/clip_image003_thumb_22.gif" width="11" border="0" v:shapes="_x0000_i1047"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span lang="EN-US" style="font-size: 12pt; color: blue; line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">else</span><span lang="EN-US" style="font-size: 12pt; color: black; line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><br></span><span lang="EN-US" style="font-size: 12pt; color: teal; line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"> 7</span><span lang="EN-US" style="font-size: 12pt; color: black; line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span lang="EN-US" style="border-right: gray 1pt solid; padding-right: 0cm; border-top: gray 1pt solid; display: none; padding-left: 0cm; font-size: 12pt; background: white; padding-bottom: 0cm; border-left: gray 1pt solid; line-height: 150%; padding-top: 0cm; border-bottom: gray 1pt solid; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt; mso-hide: all; mso-border-alt: solid gray .75pt"><a href="http://www.cppblog.com/images/cppblog_com/woaidongmao/WindowsLiveWriter/stl_D009/clip_image002_50.gif"><img title="clip_image002" style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" height="24" alt="clip_image002" src="http://www.cppblog.com/images/cppblog_com/woaidongmao/WindowsLiveWriter/stl_D009/clip_image002_thumb_16.gif" width="19" border="0" v:shapes="_x0000_i1048"></a></span><span lang="EN-US" style="font-size: 12pt; color: black; line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">{<br></span><span lang="EN-US" style="font-size: 12pt; color: teal; line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"> 8</span><span lang="EN-US" style="font-size: 12pt; color: black; line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><a href="http://www.cppblog.com/images/cppblog_com/woaidongmao/WindowsLiveWriter/stl_D009/clip_image003_68.gif"><img title="clip_image003" style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" height="16" alt="clip_image003" src="http://www.cppblog.com/images/cppblog_com/woaidongmao/WindowsLiveWriter/stl_D009/clip_image003_thumb_23.gif" width="11" border="0" v:shapes="_x0000_i1049"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf("%d:%d\n", i++, (*it)-&gt;GetI());<br></span><span lang="EN-US" style="font-size: 12pt; color: teal; line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"> 9</span><span lang="EN-US" style="font-size: 12pt; color: black; line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><a href="http://www.cppblog.com/images/cppblog_com/woaidongmao/WindowsLiveWriter/stl_D009/clip_image004_34.gif"><img title="clip_image004" style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" height="16" alt="clip_image004" src="http://www.cppblog.com/images/cppblog_com/woaidongmao/WindowsLiveWriter/stl_D009/clip_image004_thumb_13.gif" width="11" border="0" v:shapes="_x0000_i1050"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br></span><span lang="EN-US" style="font-size: 12pt; color: teal; line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">10</span><span lang="EN-US" style="font-size: 12pt; color: black; line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><a href="http://www.cppblog.com/images/cppblog_com/woaidongmao/WindowsLiveWriter/stl_D009/clip_image005_44.gif"><img title="clip_image005" style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" height="16" alt="clip_image005" src="http://www.cppblog.com/images/cppblog_com/woaidongmao/WindowsLiveWriter/stl_D009/clip_image005_thumb_19.gif" width="11" border="0" v:shapes="_x0000_i1051"></a>&nbsp;&nbsp;&nbsp; }</span><span lang="EN-US" style="font-size: 12pt; line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><o:p></o:p></span></p> <p class="MsoNormal" style="line-height: 150%; text-align: left; mso-pagination: widow-orphan" align="left"><span lang="EN-US" style="font-size: 12pt; line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><br></span><span style="font-size: 12pt; line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">两种解决方法：<span lang="EN-US"><br></span>对于顺序容器： <span lang="EN-US"><o:p></o:p></span></span></p> <p class="MsoNormal" style="background: #eeeeee; word-break: break-all; line-height: 150%; text-align: left; mso-pagination: widow-orphan" align="left"><span lang="EN-US" style="font-size: 12pt; line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><a href="http://www.cppblog.com/images/cppblog_com/woaidongmao/WindowsLiveWriter/stl_D009/clip_image001_88.gif"><img title="clip_image001" style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" height="16" alt="clip_image001" src="http://www.cppblog.com/images/cppblog_com/woaidongmao/WindowsLiveWriter/stl_D009/clip_image001_thumb_31.gif" width="11" border="0" v:shapes="_x0000_i1052"></a><span style="color: black"><br><a href="http://www.cppblog.com/images/cppblog_com/woaidongmao/WindowsLiveWriter/stl_D009/clip_image001_90.gif"><img title="clip_image001" style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" height="16" alt="clip_image001" src="http://www.cppblog.com/images/cppblog_com/woaidongmao/WindowsLiveWriter/stl_D009/clip_image001_thumb_32.gif" width="11" border="0" v:shapes="_x0000_i1053"></a></span><span style="color: blue">bool</span><span style="color: black"> Equal10(sMem* pMem)<br></span><span style="border-right: gray 1pt solid; padding-right: 0cm; border-top: gray 1pt solid; display: none; padding-left: 0cm; background: white; padding-bottom: 0cm; border-left: gray 1pt solid; padding-top: 0cm; border-bottom: gray 1pt solid; mso-hide: all; mso-border-alt: solid gray .75pt"><a href="http://www.cppblog.com/images/cppblog_com/woaidongmao/WindowsLiveWriter/stl_D009/clip_image002_52.gif"><img title="clip_image002" style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" height="24" alt="clip_image002" src="http://www.cppblog.com/images/cppblog_com/woaidongmao/WindowsLiveWriter/stl_D009/clip_image002_thumb_17.gif" width="19" border="0" v:shapes="_x0000_i1054"></a></span><span style="color: black">{<o:p></o:p></span></span></p> <p class="MsoNormal" style="background: #eeeeee; word-break: break-all; line-height: 150%; text-align: left; mso-pagination: widow-orphan" align="left"><span lang="EN-US" style="font-size: 12pt; color: black; line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">&nbsp;&nbsp;&nbsp; </span><span lang="EN-US" style="font-size: 12pt; color: blue; line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">return</span><span lang="EN-US" style="font-size: 12pt; color: black; line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"> pMem-&gt;GetI() == 10 ? </span><span lang="EN-US" style="font-size: 12pt; color: blue; line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">true</span><span lang="EN-US" style="font-size: 12pt; color: black; line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"> : </span><span lang="EN-US" style="font-size: 12pt; color: blue; line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">false</span><span lang="EN-US" style="font-size: 12pt; color: black; line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">;<br>}</span><span lang="EN-US" style="font-size: 12pt; line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><o:p></o:p></span></p> <p class="MsoNormal" style="background: #eeeeee; word-break: break-all; line-height: 150%; text-align: left; mso-pagination: widow-orphan" align="left"><span lang="EN-US" style="font-size: 12pt; color: teal; line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">1</span><span lang="EN-US" style="font-size: 12pt; line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><a href="http://www.cppblog.com/images/cppblog_com/woaidongmao/WindowsLiveWriter/stl_D009/clip_image001_92.gif"><img title="clip_image001" style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" height="16" alt="clip_image001" src="http://www.cppblog.com/images/cppblog_com/woaidongmao/WindowsLiveWriter/stl_D009/clip_image001_thumb_33.gif" width="11" border="0" v:shapes="_x0000_i1055"></a><span style="color: black">MemList.erase(remove_if(MemList.begin(), MemList.end(), Equal10));</span><o:p></o:p></span></p> <p class="MsoNormal" style="line-height: 150%; text-align: left; mso-pagination: widow-orphan" align="left"><span lang="EN-US" style="font-size: 12pt; line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><br></span><span style="font-size: 12pt; line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt">对于结点容器：<span lang="EN-US"><o:p></o:p></span></span></p> <p class="MsoNormal" style="background: #eeeeee; word-break: break-all; line-height: 150%; text-align: left; mso-pagination: widow-orphan" align="left"><span lang="EN-US" style="font-size: 12pt; color: teal; line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"> 1</span><span lang="EN-US" style="font-size: 12pt; line-height: 150%; font-family: 宋体; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt"><a href="http://www.cppblog.com/images/cppblog_com/woaidongmao/WindowsLiveWriter/stl_D009/clip_image001_94.gif"><img title="clip_image001" style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" height="16" alt="clip_image001" src="http://www.cppblog.com/images/cppblog_com/woaidongmao/WindowsLiveWriter/stl_D009/clip_image001_thumb_34.gif" width="11" border="0" v:shapes="_x0000_i1056"></a><span style="color: black">&nbsp;&nbsp;&nbsp; </span><span style="color: blue">for</span><span style="color: black"> (sIT it = MemList.begin();<br></span><span style="color: teal"> 2</span><span style="color: black"><a href="http://www.cppblog.com/images/cppblog_com/woaidongmao/WindowsLiveWriter/stl_D009/clip_image001_96.gif"><img title="clip_image001" style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" height="16" alt="clip_image001" src="http://www.cppblog.com/images/cppblog_com/woaidongmao/WindowsLiveWriter/stl_D009/clip_image001_thumb_35.gif" width="11" border="0" v:shapes="_x0000_i1057"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; it != MemList.end(); )<br></span><span style="color: teal"> 3</span><span style="color: black">&nbsp;&nbsp;&nbsp; </span><span style="border-right: gray 1pt solid; padding-right: 0cm; border-top: gray 1pt solid; display: none; padding-left: 0cm; background: white; padding-bottom: 0cm; border-left: gray 1pt solid; padding-top: 0cm; border-bottom: gray 1pt solid; mso-hide: all; mso-border-alt: solid gray .75pt"><a href="http://www.cppblog.com/images/cppblog_com/woaidongmao/WindowsLiveWriter/stl_D009/clip_image002_54.gif"><img title="clip_image002" style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" height="24" alt="clip_image002" src="http://www.cppblog.com/images/cppblog_com/woaidongmao/WindowsLiveWriter/stl_D009/clip_image002_thumb_18.gif" width="19" border="0" v:shapes="_x0000_i1058"></a></span><span style="color: black">{<br></span><span style="color: teal"> 4</span><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: blue">if</span><span style="color: black"> ((*it).second-&gt;GetI() == 10)<br></span><span style="color: teal"> 5</span><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MemList.erase(it++);<br></span><span style="color: teal"> 6</span><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: blue">else</span><span style="color: black"><br></span><span style="color: teal"> 7</span><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="border-right: gray 1pt solid; padding-right: 0cm; border-top: gray 1pt solid; display: none; padding-left: 0cm; background: white; padding-bottom: 0cm; border-left: gray 1pt solid; padding-top: 0cm; border-bottom: gray 1pt solid; mso-hide: all; mso-border-alt: solid gray .75pt"><a href="http://www.cppblog.com/images/cppblog_com/woaidongmao/WindowsLiveWriter/stl_D009/clip_image002_56.gif"><img title="clip_image002" style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" height="24" alt="clip_image002" src="http://www.cppblog.com/images/cppblog_com/woaidongmao/WindowsLiveWriter/stl_D009/clip_image002_thumb_19.gif" width="19" border="0" v:shapes="_x0000_i1059"></a></span><span style="color: black">{<br></span><span style="color: teal"> 8</span><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf("%d:%d\n", i++, (*it).second-&gt;GetI());<br></span><span style="color: teal"> 9</span><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; it++;<br></span><span style="color: teal">10</span><span style="color: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br></span><span style="color: teal">11</span><span style="color: black">&nbsp;&nbsp;&nbsp; }</span><o:p></o:p></span></p> <p class="MsoNormal"><span lang="EN-US" style="font-size: 12pt; font-family: 宋体; mso-bidi-font-family: arial"><o:p>&nbsp;</o:p></span></p><img src ="http://www.cppblog.com/woaidongmao/aggbug/89653.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/woaidongmao/" target="_blank">肥仔</a> 2009-07-09 14:48 <a href="http://www.cppblog.com/woaidongmao/archive/2009/07/09/89653.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>stlport的link error</title><link>http://www.cppblog.com/woaidongmao/archive/2009/05/18/83275.html</link><dc:creator>肥仔</dc:creator><author>肥仔</author><pubDate>Mon, 18 May 2009 06:32:00 GMT</pubDate><guid>http://www.cppblog.com/woaidongmao/archive/2009/05/18/83275.html</guid><wfw:comment>http://www.cppblog.com/woaidongmao/comments/83275.html</wfw:comment><comments>http://www.cppblog.com/woaidongmao/archive/2009/05/18/83275.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/woaidongmao/comments/commentRss/83275.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/woaidongmao/services/trackbacks/83275.html</trackback:ping><description><![CDATA[<p><br>一下几个步骤组合会引发这个问题<br>1、在stdafx.h中定义了&#8220;_STLP_USE_STATIC_LIB&#8221;，使用静态库连接；<br>2、但是的有cpp文件使用了STLPort，但是设置为不使用头文件，也就是没有#include"stdafx.h"；<br><br>解决办法：<br>把&#8220;_STLP_USE_STATIC_LIB&#8221;的定义放在 Project Settings里面。</p>
<img src ="http://www.cppblog.com/woaidongmao/aggbug/83275.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/woaidongmao/" target="_blank">肥仔</a> 2009-05-18 14:32 <a href="http://www.cppblog.com/woaidongmao/archive/2009/05/18/83275.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>STL 仿函数列表</title><link>http://www.cppblog.com/woaidongmao/archive/2008/11/09/66384.html</link><dc:creator>肥仔</dc:creator><author>肥仔</author><pubDate>Sat, 08 Nov 2008 17:14:00 GMT</pubDate><guid>http://www.cppblog.com/woaidongmao/archive/2008/11/09/66384.html</guid><wfw:comment>http://www.cppblog.com/woaidongmao/comments/66384.html</wfw:comment><comments>http://www.cppblog.com/woaidongmao/archive/2008/11/09/66384.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/woaidongmao/comments/commentRss/66384.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/woaidongmao/services/trackbacks/66384.html</trackback:ping><description><![CDATA[<table class="MsoNormalTable" style="mso-cellspacing: 1.5pt" cellpadding="0" border="0"> <tbody> <tr style="mso-yfti-irow: 0; mso-yfti-firstrow: yes"> <td style="padding-right: 0.75pt; padding-left: 0.75pt; padding-bottom: 0.75pt; padding-top: 0.75pt"> <p><span lang="EN-US"><?xml:namespace prefix = o /><o:p>&nbsp;</o:p></span></p></td></tr> <tr style="mso-yfti-irow: 1"> <td style="padding-right: 0.75pt; padding-left: 0.75pt; background: #dadada; padding-bottom: 0.75pt; padding-top: 0.75pt" colspan="2"> <p class="MsoNormal" style="text-align: center" align="center"><b><span lang="EN-US" style="font-size: 12pt; font-family: 宋体"><a title="Sort by this column" href="http://www.stlchina.org/twiki/bin/view.pl/Main/STLSortAlgorithms?sortcol=0;table=2;up=0#sorted_table"><span lang="EN-US" style="color: black"><span lang="EN-US">名称</span></span><span lang="EN-US" style="color: black"><span lang="EN-US"> </span></span></a></span></b><b><span lang="EN-US" style="font-size: 12pt; font-family: 宋体; mso-bidi-font-family: 宋体"><o:p></o:p></span></b></p></td> <td style="padding-right: 0.75pt; padding-left: 0.75pt; background: #dadada; padding-bottom: 0.75pt; padding-top: 0.75pt"> <p class="MsoNormal" style="text-align: center" align="center"><b><span lang="EN-US" style="font-size: 12pt; font-family: 宋体"><a title="Sort by this column" href="http://www.stlchina.org/twiki/bin/view.pl/Main/STLSortAlgorithms?sortcol=1;table=2;up=0#sorted_table"><span lang="EN-US" style="color: black"><span lang="EN-US">功能描述</span></span><span lang="EN-US" style="color: black"><span lang="EN-US"> </span></span></a></span></b><b><span lang="EN-US" style="font-size: 12pt; font-family: 宋体; mso-bidi-font-family: 宋体"><o:p></o:p></span></b></p></td></tr> <tr style="mso-yfti-irow: 2"> <td style="padding-right: 0.75pt; padding-left: 0.75pt; background: white; padding-bottom: 0.75pt; padding-top: 0.75pt" colspan="2"> <p class="MsoNormal"><span lang="EN-US" style="font-size: 12pt; font-family: 宋体">equal_to</span><span lang="EN-US" style="font-size: 12pt; font-family: 宋体; mso-bidi-font-family: 宋体"><o:p></o:p></span></p></td> <td style="padding-right: 0.75pt; padding-left: 0.75pt; background: white; padding-bottom: 0.75pt; padding-top: 0.75pt"> <p class="MsoNormal"><span style="font-size: 12pt; font-family: 宋体">相等</span><span lang="EN-US" style="font-size: 12pt; font-family: 宋体; mso-bidi-font-family: 宋体"><o:p></o:p></span></p></td></tr> <tr style="mso-yfti-irow: 3"> <td style="padding-right: 0.75pt; padding-left: 0.75pt; background: #eaeaea; padding-bottom: 0.75pt; padding-top: 0.75pt" colspan="2"> <p class="MsoNormal"><span lang="EN-US" style="font-size: 12pt; font-family: 宋体">not_equal_to</span><span lang="EN-US" style="font-size: 12pt; font-family: 宋体; mso-bidi-font-family: 宋体"><o:p></o:p></span></p></td> <td style="padding-right: 0.75pt; padding-left: 0.75pt; background: #eaeaea; padding-bottom: 0.75pt; padding-top: 0.75pt"> <p class="MsoNormal"><span style="font-size: 12pt; font-family: 宋体">不相等</span><span lang="EN-US" style="font-size: 12pt; font-family: 宋体; mso-bidi-font-family: 宋体"><o:p></o:p></span></p></td></tr> <tr style="mso-yfti-irow: 4"> <td style="padding-right: 0.75pt; padding-left: 0.75pt; background: white; padding-bottom: 0.75pt; padding-top: 0.75pt" colspan="2"> <p class="MsoNormal"><span lang="EN-US" style="font-size: 12pt; font-family: 宋体">less</span><span lang="EN-US" style="font-size: 12pt; font-family: 宋体; mso-bidi-font-family: 宋体"><o:p></o:p></span></p></td> <td style="padding-right: 0.75pt; padding-left: 0.75pt; background: white; padding-bottom: 0.75pt; padding-top: 0.75pt"> <p class="MsoNormal"><span style="font-size: 12pt; font-family: 宋体">小于</span><span lang="EN-US" style="font-size: 12pt; font-family: 宋体; mso-bidi-font-family: 宋体"><o:p></o:p></span></p></td></tr> <tr style="mso-yfti-irow: 5"> <td style="padding-right: 0.75pt; padding-left: 0.75pt; background: #eaeaea; padding-bottom: 0.75pt; padding-top: 0.75pt" colspan="2"> <p class="MsoNormal"><span lang="EN-US" style="font-size: 12pt; font-family: 宋体">greater</span><span lang="EN-US" style="font-size: 12pt; font-family: 宋体; mso-bidi-font-family: 宋体"><o:p></o:p></span></p></td> <td style="padding-right: 0.75pt; padding-left: 0.75pt; background: #eaeaea; padding-bottom: 0.75pt; padding-top: 0.75pt"> <p class="MsoNormal"><span style="font-size: 12pt; font-family: 宋体">大于</span><span lang="EN-US" style="font-size: 12pt; font-family: 宋体; mso-bidi-font-family: 宋体"><o:p></o:p></span></p></td></tr> <tr style="mso-yfti-irow: 6"> <td style="padding-right: 0.75pt; padding-left: 0.75pt; background: white; padding-bottom: 0.75pt; padding-top: 0.75pt" colspan="2"> <p class="MsoNormal"><span lang="EN-US" style="font-size: 12pt; font-family: 宋体">less_equal</span><span lang="EN-US" style="font-size: 12pt; font-family: 宋体; mso-bidi-font-family: 宋体"><o:p></o:p></span></p></td> <td style="padding-right: 0.75pt; padding-left: 0.75pt; background: white; padding-bottom: 0.75pt; padding-top: 0.75pt"> <p class="MsoNormal"><span style="font-size: 12pt; font-family: 宋体">小于等于</span><span lang="EN-US" style="font-size: 12pt; font-family: 宋体; mso-bidi-font-family: 宋体"><o:p></o:p></span></p></td></tr> <tr style="mso-yfti-irow: 7; mso-yfti-lastrow: yes"> <td style="padding-right: 0.75pt; padding-left: 0.75pt; background: #eaeaea; padding-bottom: 0.75pt; padding-top: 0.75pt" colspan="2"> <p class="MsoNormal"><span lang="EN-US" style="font-size: 12pt; font-family: 宋体">greater_equal</span><span lang="EN-US" style="font-size: 12pt; font-family: 宋体; mso-bidi-font-family: 宋体"><o:p></o:p></span></p></td> <td style="padding-right: 0.75pt; padding-left: 0.75pt; background: #eaeaea; padding-bottom: 0.75pt; padding-top: 0.75pt"> <p class="MsoNormal"><span style="font-size: 12pt; font-family: 宋体">大于等于</span><span lang="EN-US" style="font-size: 12pt; font-family: 宋体; mso-bidi-font-family: 宋体"><o:p></o:p></span></p></td></tr> <tr height="0"> <td style="border-right: medium none; border-top: medium none; border-left: medium none; border-bottom: medium none" width="67"></td> <td style="border-right: medium none; border-top: medium none; border-left: medium none; border-bottom: medium none" width="42"></td> <td style="border-right: medium none; border-top: medium none; border-left: medium none; border-bottom: medium none" width="73"></td></tr></tbody></table> <p>实例：<span lang="EN-US"><br>//less&lt;int&gt;()</span>默认排序－－升序<span lang="EN-US"><br>//greater&lt;int&gt;()<br>vector &lt; <span style="color: brown">int</span> &gt; vect;<span style="color: green"><br>//...</span><br>sort(vect.begin(), vect.end());<span style="color: green"><br>//</span></span><span style="color: green">此时相当于调用</span><span lang="EN-US"><br>sort(vect.begin(), vect.end(), less&lt;<span style="color: brown">int</span>&gt;() );<o:p></o:p></span></p> <p class="MsoNormal"><span lang="EN-US" style="font-size: 12pt; font-family: 宋体"><a href="http://www.stlchina.org/twiki/bin/view.pl/Main/STLSortAlgorithms?sortcol=0;table=2;up=0#sorted_table">http://www.stlchina.org/twiki/bin/view.pl/Main/STLSortAlgorithms?sortcol=0;table=2;up=0#sorted_table</a></span><span lang="EN-US" style="font-size: 12pt; font-family: 宋体; mso-bidi-font-family: arial"><o:p></o:p></span></p><img src ="http://www.cppblog.com/woaidongmao/aggbug/66384.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/woaidongmao/" target="_blank">肥仔</a> 2008-11-09 01:14 <a href="http://www.cppblog.com/woaidongmao/archive/2008/11/09/66384.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>std::find用法错误记录</title><link>http://www.cppblog.com/woaidongmao/archive/2008/11/06/66130.html</link><dc:creator>肥仔</dc:creator><author>肥仔</author><pubDate>Thu, 06 Nov 2008 07:33:00 GMT</pubDate><guid>http://www.cppblog.com/woaidongmao/archive/2008/11/06/66130.html</guid><wfw:comment>http://www.cppblog.com/woaidongmao/comments/66130.html</wfw:comment><comments>http://www.cppblog.com/woaidongmao/archive/2008/11/06/66130.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/woaidongmao/comments/commentRss/66130.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/woaidongmao/services/trackbacks/66130.html</trackback:ping><description><![CDATA[<p>//---- std::find返回的是找到的迭代器位置，如果没有找到，会返回last iter，其他算法类似</p> <p>int data[32] = {0};</p> <p>int* pFind = NULL;</p> <p>if(<font color="#ff0000">pFind</font> = std::find_if(data, data + sizeof(data)/sizeof(int), cmp_fun))//---判断找到了</p> <p>&nbsp;</p> <p>//---- 正确的是</p> <p>if((data + sizeof(data)/sizeof(int)) != (<font color="#ff0000">pFind</font> = std::find_if(data, data + sizeof(data)/sizeof(int), cmp_fun)))//---判断找到了</p><img src ="http://www.cppblog.com/woaidongmao/aggbug/66130.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/woaidongmao/" target="_blank">肥仔</a> 2008-11-06 15:33 <a href="http://www.cppblog.com/woaidongmao/archive/2008/11/06/66130.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>STLPort 的预定义</title><link>http://www.cppblog.com/woaidongmao/archive/2008/10/20/64468.html</link><dc:creator>肥仔</dc:creator><author>肥仔</author><pubDate>Mon, 20 Oct 2008 02:16:00 GMT</pubDate><guid>http://www.cppblog.com/woaidongmao/archive/2008/10/20/64468.html</guid><wfw:comment>http://www.cppblog.com/woaidongmao/comments/64468.html</wfw:comment><comments>http://www.cppblog.com/woaidongmao/archive/2008/10/20/64468.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/woaidongmao/comments/commentRss/64468.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/woaidongmao/services/trackbacks/64468.html</trackback:ping><description><![CDATA[<p>&nbsp;</p> <p><strong>一、使用静态连接，否则需要stlport的dll</strong></p> <p>#define _STLP_USE_STATIC_LIB</p> <p>放到ALT+F7-&gt;C++-&gt;Preprocessor definitions里面即可（DEBUG和RELEASE都改）</p><img src ="http://www.cppblog.com/woaidongmao/aggbug/64468.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/woaidongmao/" target="_blank">肥仔</a> 2008-10-20 10:16 <a href="http://www.cppblog.com/woaidongmao/archive/2008/10/20/64468.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Boost Serialization 库教程</title><link>http://www.cppblog.com/woaidongmao/archive/2008/10/19/64345.html</link><dc:creator>肥仔</dc:creator><author>肥仔</author><pubDate>Sat, 18 Oct 2008 16:38:00 GMT</pubDate><guid>http://www.cppblog.com/woaidongmao/archive/2008/10/19/64345.html</guid><wfw:comment>http://www.cppblog.com/woaidongmao/comments/64345.html</wfw:comment><comments>http://www.cppblog.com/woaidongmao/archive/2008/10/19/64345.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/woaidongmao/comments/commentRss/64345.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/woaidongmao/services/trackbacks/64345.html</trackback:ping><description><![CDATA[<p>输出档案(archive)类似于输出数据流(stream)。数据能通过&lt;&lt; 或 &amp; 操作符存储到档案(archive)中: <pre><code>&nbsp;</code></pre><pre><code>ar &lt;&lt; data;</code></pre><pre><code>ar &amp; data;</code></pre>
<p>输入档案(archive)类似于输入数据流(stream)。数据能通过&gt;&gt; 或 &amp; 操作符从档案(archive)中装载。 <pre><code>&nbsp;</code></pre><pre><code>ar &gt;&gt; data;</code></pre><pre><code>ar &amp; data;</code></pre>
<p>对于原始数据类型，当这些操作调用的时候，数据是简单的“被存储/被装载” “到/从” 档案(archive)。对于类(class)数据类型，类的serialize 函数被调用。对上面的操作，每个serialize 函数用来“存储/装载”其数据成员。这个处理采用递归的方式，直到所有包含在类中的数据“被存储/被装载”。
<p>&nbsp; <h5><a name="simplecase">一个非常简单的情形</a></h5>
<p>通常用serialize 函数来存储和装载类的数据成员。 
<p>这个库包含一个叫 <a href="http://www.boost.org/libs/serialization/example/demo.cpp">demo.cpp</a> 的程序，用于介绍如何用这个库。下面，我们从这个demo摘录代码，来介绍这个库应用的最简单情形。<pre><code>&nbsp;</code></pre><pre><code>#include &lt;fstream&gt;</code></pre><pre><code>&nbsp;</code></pre><pre><code>// include headers that implement a archive in simple text format</code></pre><pre><code>#include &lt;boost/archive/text_oarchive.hpp&gt;</code></pre><pre><code>#include &lt;boost/archive/text_iarchive.hpp&gt;</code></pre><pre><code>&nbsp;</code></pre><pre><code>/////////////////////////////////////////////////////////////</code></pre><pre><code>// gps coordinate</code></pre><pre><code>//</code></pre><pre><code>// illustrates serialization for a simple type</code></pre><pre><code>//</code></pre><pre><code>class gps_position</code></pre><pre><code>{</code></pre><pre><code>private:</code></pre><pre><code>&nbsp;&nbsp;&nbsp; friend class boost::serialization::access;</code></pre><pre><code>&nbsp;&nbsp;&nbsp; // When the class Archive corresponds to an output archive, the</code></pre><pre><code>&nbsp;&nbsp;&nbsp; // &amp; operator is defined similar to &lt;&lt;.&nbsp; Likewise, when the class Archive</code></pre><pre><code>&nbsp;&nbsp;&nbsp; // is a type of input archive the &amp; operator is defined similar to &gt;&gt;.</code></pre><pre><code>&nbsp;&nbsp;&nbsp; template&lt;class Archive&gt;</code></pre><pre><code>&nbsp;&nbsp;&nbsp; void serialize(Archive &amp; ar, const unsigned int version)</code></pre><pre><code>&nbsp;&nbsp;&nbsp; {</code></pre><pre><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ar &amp; degrees;</code></pre><pre><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ar &amp; minutes;</code></pre><pre><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ar &amp; seconds;</code></pre><pre><code>&nbsp;&nbsp;&nbsp; }</code></pre><pre><code>&nbsp;&nbsp;&nbsp; int degrees;</code></pre><pre><code>&nbsp;&nbsp;&nbsp; int minutes;</code></pre><pre><code>&nbsp;&nbsp;&nbsp; float seconds;</code></pre><pre><code>public:</code></pre><pre><code>&nbsp;&nbsp;&nbsp; gps_position(){};</code></pre><pre><code>&nbsp;&nbsp;&nbsp; gps_position(int d, int m, float s) :</code></pre><pre><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; degrees(d), minutes(m), seconds(s)</code></pre><pre><code>&nbsp;&nbsp;&nbsp; {}</code></pre><pre><code>};</code></pre><pre><code>&nbsp;</code></pre><pre><code>int main() {</code></pre><pre><code>&nbsp;&nbsp;&nbsp; // create and open a character archive for output</code></pre><pre><code>&nbsp;&nbsp;&nbsp; std::ofstream ofs("filename");</code></pre><pre><code>&nbsp;&nbsp;&nbsp; boost::archive::text_oarchive oa(ofs);</code></pre><pre><code>&nbsp;</code></pre><pre><code>&nbsp;&nbsp;&nbsp; // create class instance</code></pre><pre><code>&nbsp;&nbsp;&nbsp; const gps_position g(35, 59, 24.567f);</code></pre><pre><code>&nbsp;&nbsp;&nbsp; // write class instance to archive</code></pre><pre><code>&nbsp;&nbsp;&nbsp; oa &lt;&lt; g;</code></pre><pre><code>&nbsp;&nbsp;&nbsp; // close archive</code></pre><pre><code>&nbsp;&nbsp;&nbsp; ofs.close();</code></pre><pre><code>&nbsp;</code></pre><pre><code>&nbsp;&nbsp;&nbsp; // ... some time later restore the class instance to its orginal state</code></pre><pre><code>&nbsp;&nbsp;&nbsp; // create and open an archive for input</code></pre><pre><code>&nbsp;&nbsp;&nbsp; std::ifstream ifs("filename", std::ios::binary);</code></pre><pre><code>&nbsp;&nbsp;&nbsp; boost::archive::text_iarchive ia(ifs);</code></pre><pre><code>&nbsp;&nbsp;&nbsp; // read class state from archive</code></pre><pre><code>&nbsp;&nbsp;&nbsp; gps_position newg;</code></pre><pre><code>&nbsp;&nbsp;&nbsp; ia &gt;&gt; newg;</code></pre><pre><code>&nbsp;&nbsp;&nbsp; // close archive</code></pre><pre><code>&nbsp;&nbsp;&nbsp; ifs.close();</code></pre><pre><code>&nbsp;&nbsp;&nbsp; return 0;</code></pre><pre><code>}</code></pre><pre>&nbsp;</pre>
<p>对于每个通过序列化“被存储”的类，必须存在一个函数去实现“存储”其所有状态数据。对于每个通过序列化“被装载”的类，必须存在一个函数来实现“装载”其所有状态数据。在上面的例子中，这些函数是模板成员函数serialize。 
<p>&nbsp; <h5><a name="nonintrusiveversion">非侵入的版本</a></h5>
<p>在上例是侵入的设计。类是需要由其实例来序列化，来改变。这在某些情形是困难的。一个等价的可选的设计如下：<pre><code>&nbsp;</code></pre><pre><code>#include &lt;boost/archive/text_oarchive.hpp&gt;</code></pre><pre><code>#include &lt;boost/archive/text_iarchive.hpp&gt;</code></pre><pre><code>&nbsp;</code></pre><pre><code>class gps_position</code></pre><pre><code>{</code></pre><pre><code>public:</code></pre><pre><code>&nbsp;&nbsp;&nbsp; int degrees;</code></pre><pre><code>&nbsp;&nbsp;&nbsp; int minutes;</code></pre><pre><code>&nbsp;&nbsp;&nbsp; float seconds;</code></pre><pre><code>&nbsp;&nbsp;&nbsp; gps_position(){};</code></pre><pre><code>&nbsp;&nbsp;&nbsp; gps_position(int d, int m, float s) :</code></pre><pre><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; degrees(d), minutes(m), seconds(s)</code></pre><pre><code>&nbsp;&nbsp;&nbsp; {}</code></pre><pre><code>};</code></pre><pre><code>&nbsp;</code></pre><pre><code>namespace boost {</code></pre><pre><code>namespace serialization {</code></pre><pre><code>&nbsp;</code></pre><pre><code>template&lt;class Archive&gt;</code></pre><pre><code>void serialize(Archive &amp; ar, gps_position &amp; g, const unsigned int version)</code></pre><pre><code>{</code></pre><pre><code>&nbsp;&nbsp;&nbsp; ar &amp; g.degrees;</code></pre><pre><code>&nbsp;&nbsp;&nbsp; ar &amp; g.minutes;</code></pre><pre><code>&nbsp;&nbsp;&nbsp; ar &amp; g.seconds;</code></pre><pre><code>}</code></pre><pre><code>&nbsp;</code></pre><pre><code>} // namespace serialization</code></pre><pre><code>} // namespace boost</code></pre>
<p>这种情况生成的serialize 函数不是gps_position类的成员函数。这有异曲同工之妙。 
<p>非侵入序列化主要应用在不改变类定义就可实现类的序列化。为实现这种可能，类必须提供足够的信息来更新类状态。在这个例子中，我们假设类有public成员。仅当提供足够信息来存储和装载的类，才能不改变类自身，在外部来序列化类状态。 
<p>&nbsp; <h5><a name="serializablemembers">可序列化的成员</a></h5>
<p>一个可序列化的类，可拥有可序列化的成员，例如： <pre><code>&nbsp;</code></pre><pre><code>class bus_stop</code></pre><pre><code>{</code></pre><pre><code>&nbsp;&nbsp;&nbsp; friend class boost::serialization::access;</code></pre><pre><code>&nbsp;&nbsp;&nbsp; template&lt;class Archive&gt;</code></pre><pre><code>&nbsp;&nbsp;&nbsp; void serialize(Archive &amp; ar, const unsigned int version)</code></pre><pre><code>&nbsp;&nbsp;&nbsp; {</code></pre><pre><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ar &amp; latitude;</code></pre><pre><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ar &amp; longitude;</code></pre><pre><code>&nbsp;&nbsp;&nbsp; }</code></pre><pre><code>&nbsp;&nbsp;&nbsp; gps_position latitude;</code></pre><pre><code>&nbsp;&nbsp;&nbsp; gps_position longitude;</code></pre><pre><code>protected:</code></pre><pre><code>&nbsp;&nbsp;&nbsp; bus_stop(const gps_position &amp; lat_, const gps_position &amp; long_) :</code></pre><pre><code>&nbsp;&nbsp;&nbsp; latitude(lat_), longitude(long_)</code></pre><pre><code>&nbsp;&nbsp;&nbsp; {}</code></pre><pre><code>public:</code></pre><pre><code>&nbsp;&nbsp;&nbsp; bus_stop(){}</code></pre><pre><code>&nbsp;&nbsp;&nbsp; // See item # 14 in Effective C++ by Scott Meyers.</code></pre><pre><code>&nbsp;&nbsp;&nbsp; // re non-virtual destructors in base classes.</code></pre><pre><code>&nbsp;&nbsp;&nbsp; virtual ~bus_stop(){}</code></pre><pre><code>};</code></pre>
<p>这里，类类型的成员被序列化，恰如原始类型被序列化一样。 
<p>注意，类bus_stop的实例“存储”时，其归档(archive)操作符将调用latitude 和 longitude的serialize 函数。这将依次调用定义在gps_position中的serialize 来被“存储”。这种手法中，通过<code>bus_stop</code>的归档(archive)操作符,整个数据结构被存储,<code>bus_stop</code>是它的根条目。
<p>&nbsp; <h5><a name="derivedclasses">派生类</a></h5>
<p>派生类应包含其基类的序列化。 <pre><code>&nbsp;</code></pre><pre><code>#include &lt;boost/serialization/base_object.hpp&gt;</code></pre><pre><code>&nbsp;</code></pre><pre><code>class bus_stop_corner : public bus_stop</code></pre><pre><code>{</code></pre><pre><code>&nbsp;&nbsp;&nbsp; friend class boost::serialization::access;</code></pre><pre><code>&nbsp;&nbsp;&nbsp; template&lt;class Archive&gt;</code></pre><pre><code>&nbsp;&nbsp;&nbsp; void serialize(Archive &amp; ar, const unsigned int version)</code></pre><pre><code>&nbsp;&nbsp;&nbsp; {</code></pre><pre><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // serialize base class information</code></pre><pre><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ar &amp; boost::serialization::base_object&lt;bus_stop&gt;(*this);</code></pre><pre><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ar &amp; street1;</code></pre><pre><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ar &amp; street2;</code></pre><pre><code>&nbsp;&nbsp;&nbsp; }</code></pre><pre><code>&nbsp;&nbsp;&nbsp; std::string street1;</code></pre><pre><code>&nbsp;&nbsp;&nbsp; std::string street2;</code></pre><pre><code>&nbsp;&nbsp;&nbsp; virtual std::string description() const</code></pre><pre><code>&nbsp;&nbsp;&nbsp; {</code></pre><pre><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return street1 + " and " + street2;</code></pre><pre><code>&nbsp;&nbsp;&nbsp; }</code></pre><pre><code>public:</code></pre><pre><code>&nbsp;&nbsp;&nbsp; bus_stop_corner(){}</code></pre><pre><code>&nbsp;&nbsp;&nbsp; bus_stop_corner(const gps_position &amp; lat_, const gps_position &amp; long_,</code></pre><pre><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; const std::string &amp; s1_, const std::string &amp; s2_</code></pre><pre><code>&nbsp;&nbsp;&nbsp; ) :</code></pre><pre><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bus_stop(lat_, long_), street1(s1_), street2(s2_)</code></pre><pre><code>&nbsp;&nbsp;&nbsp; {}</code></pre><pre><code>};</code></pre><pre>&nbsp;</pre>
<p>注意在派生类中不要直接调用其基类的序列化函数。这样做看似工作，实际上绕过跟踪实例用于存储来消除冗余的代码。它也绕过写到档案中类的版本信息的代码。因此，总是声明serialize 作为私有函数。声明friend boost::serialization::access 将运行序列化库存取私有变量和函数。
<p>&nbsp; <h5><a name="pointers">指针</a></h5>
<p>假设我们定义了bus route包含一组bus stops。假定： 
<ol>
<li>我们可以有几种bus stop的类型（记住bus_stop是一个基类）。 
<li>一个所给的 bus_stop可以展现多于一个的路线。 </li></ol>
<p>一个bus route 用一组指向bus_stop的指针来描述是方便的。<pre><code>&nbsp;</code></pre><pre><code>class bus_route</code></pre><pre><code>{</code></pre><pre><code>&nbsp;&nbsp;&nbsp; friend class boost::serialization::access;</code></pre><pre><code>&nbsp;&nbsp;&nbsp; bus_stop * stops[10];</code></pre><pre><code>&nbsp;&nbsp;&nbsp; template&lt;class Archive&gt;</code></pre><pre><code>&nbsp;&nbsp;&nbsp; void serialize(Archive &amp; ar, const unsigned int version)</code></pre><pre><code>&nbsp;&nbsp;&nbsp; {</code></pre><pre><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int i;</code></pre><pre><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for(i = 0; i &lt; 10; ++i)</code></pre><pre><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ar &amp; stops[i];</code></pre><pre><code>&nbsp;&nbsp;&nbsp; }</code></pre><pre><code>public:</code></pre><pre><code>&nbsp;&nbsp;&nbsp; bus_route(){}</code></pre><pre><code>};</code></pre><pre>&nbsp;</pre>
<p>数组stops 的每个成员将被序列化。但是，记住每个成员是个指针。 - 实际含义是什么？序列化整个对象是要求在另一个地方和时间重新构造原始数据结构。用指针为了完成这些，存储指针的值是不够的，指针指向的对象必须存储。当成员最后被装载，一个新的对象被创建，新的指针被装载到类的成员中。 
<p>所有这一切是由序列化库自动完成的。通过指针关联的对象，上述代码能完成存储和装载。
<p>&nbsp; <h5><a name="arrays">数组</a></h5>
<p>事实上上述方案比较复杂。序列化库能检测出被序列化的对象是一个数组，将产生上述等价的代码。因此上述代码能更短的写为：<pre><code>&nbsp;</code></pre><pre><code>class bus_route</code></pre><pre><code>{</code></pre><pre><code>&nbsp;&nbsp;&nbsp; friend class boost::serialization::access;</code></pre><pre><code>&nbsp;&nbsp;&nbsp; bus_stop * stops[10];</code></pre><pre><code>&nbsp;&nbsp;&nbsp; template&lt;class Archive&gt;</code></pre><pre><code>&nbsp;&nbsp;&nbsp; void serialize(Archive &amp; ar, const unsigned int version)</code></pre><pre><code>&nbsp;&nbsp;&nbsp; {</code></pre><pre><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ar &amp; stops;</code></pre><pre><code>&nbsp;&nbsp;&nbsp; }</code></pre><pre><code>public:</code></pre><pre><code>&nbsp;&nbsp;&nbsp; bus_route(){}</code></pre><pre><code>};</code></pre><pre>&nbsp;</pre>
<h5><a name="stl">STL</a>容器</h5>
<p>上面的例子用数组成员。更多的如此的一个应用用STL容器为如此的目的。序列化库包含为所有STL容器序列化的代码。因此，下种方案正如我们所预期的样子工作。<pre><code>&nbsp;</code></pre><pre><code>#include &lt;boost/serialization/list.hpp&gt;</code></pre><pre><code>&nbsp;</code></pre><pre><code>class bus_route</code></pre><pre><code>{</code></pre><pre><code>&nbsp;&nbsp;&nbsp; friend class boost::serialization::access;</code></pre><pre><code>&nbsp;&nbsp;&nbsp; std::list&lt;bus_stop *&gt; stops;</code></pre><pre><code>&nbsp;&nbsp;&nbsp; template&lt;class Archive&gt;</code></pre><pre><code>&nbsp;&nbsp;&nbsp; void serialize(Archive &amp; ar, const unsigned int version)</code></pre><pre><code>&nbsp;&nbsp;&nbsp; {</code></pre><pre><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ar &amp; stops;</code></pre><pre><code>&nbsp;&nbsp;&nbsp; }</code></pre><pre><code>public:</code></pre><pre><code>&nbsp;&nbsp;&nbsp; bus_route(){}</code></pre><pre><code>};</code></pre><pre>&nbsp;</pre>
<h5><a name="versioning">类的版本</a></h5>
<p>假设我们对bus_route类满意，在产品中使用它。一段时间后，发觉bus_route 类需要包含线路驾驶员的名字。因此新版本如下： <pre><code>&nbsp;</code></pre><pre><code>#include &lt;boost/serialization/list.hpp&gt;</code></pre><pre><code>#include &lt;boost/serialization/string.hpp&gt;</code></pre><pre><code>&nbsp;</code></pre><pre><code>class bus_route</code></pre><pre><code>{</code></pre><pre><code>&nbsp;&nbsp;&nbsp; friend class boost::serialization::access;</code></pre><pre><code>&nbsp;&nbsp;&nbsp; std::list&lt;bus_stop *&gt; stops;</code></pre><pre><code>&nbsp;&nbsp;&nbsp; std::string driver_name;</code></pre><pre><code>&nbsp;&nbsp;&nbsp; template&lt;class Archive&gt;</code></pre><pre><code>&nbsp;&nbsp;&nbsp; void serialize(Archive &amp; ar, const unsigned int version)</code></pre><pre><code>&nbsp;&nbsp;&nbsp; {</code></pre><pre><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ar &amp; driver_name;</code></pre><pre><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ar &amp; stops;</code></pre><pre><code>&nbsp;&nbsp;&nbsp; }</code></pre><pre><code>public:</code></pre><pre><code>&nbsp;&nbsp;&nbsp; bus_route(){}</code></pre><pre><code>};</code></pre><pre>&nbsp;</pre>
<p>好，完毕！异常...会发生在读取旧版本所生成的数据文件时。如何考虑版本问题？ 
<p>通常，序列化库为每个被序列化的类在档案中存储版本号。缺省值是0。当档案装载时，存储的版本号可被读出。上述代码可修改如下：<pre><code>&nbsp;</code></pre><pre><code>#include &lt;boost/serialization/list.hpp&gt;</code></pre><pre><code>#include &lt;boost/serialization/string.hpp&gt;</code></pre><pre><code>#include &lt;boost/serialization/version.hpp&gt;</code></pre><pre><code>&nbsp;</code></pre><pre><code>class bus_route</code></pre><pre><code>{</code></pre><pre><code>&nbsp;&nbsp;&nbsp; friend class boost::serialization::access;</code></pre><pre><code>&nbsp;&nbsp;&nbsp; std::list&lt;bus_stop *&gt; stops;</code></pre><pre><code>&nbsp;&nbsp;&nbsp; std::string driver_name;</code></pre><pre><code>&nbsp;&nbsp;&nbsp; template&lt;class Archive&gt;</code></pre><pre><code>&nbsp;&nbsp;&nbsp; void serialize(Archive &amp; ar, const unsigned int version)</code></pre><pre><code>&nbsp;&nbsp;&nbsp; {</code></pre><pre><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // only save/load driver_name for newer archives</code></pre><pre><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(version &gt; 0)</code></pre><pre><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ar &amp; driver_name;</code></pre><pre><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ar &amp; stops;</code></pre><pre><code>&nbsp;&nbsp;&nbsp; }</code></pre><pre><code>public:</code></pre><pre><code>&nbsp;&nbsp;&nbsp; bus_route(){}</code></pre><pre><code>};</code></pre><pre><code>&nbsp;</code></pre><pre><code>BOOST_CLASS_VERSION(bus_route, 1)</code></pre><pre>&nbsp;</pre>
<p>对每个类通过应用的版本，没有必要维护一个版本文件。一个文件版本是所有它组成的类的版本的联合。系统允许程序和以前版本的程序创建的档案向下兼容。 
<p>&nbsp; <h5><a name="splitting">把serialize拆分成save/load</a></h5>
<p>serialize函数是简单，简洁，并且保证类成员按同样的顺序（序列化系统的key）被存储/被装载。可是有像这里例子一样，装载和存储不一致的情形。例如，一个类有多个版本的情况发生。上述情形能重写为：<pre><code>&nbsp;</code></pre><pre><code>#include &lt;boost/serialization/list.hpp&gt;</code></pre><pre><code>#include &lt;boost/serialization/string.hpp&gt;</code></pre><pre><code>#include &lt;boost/serialization/version.hpp&gt;</code></pre><pre><code>#include &lt;boost/serialization/split_member.hpp&gt;</code></pre><pre><code>&nbsp;</code></pre><pre><code>class bus_route</code></pre><pre><code>{</code></pre><pre><code>&nbsp;&nbsp;&nbsp; friend class boost::serialization::access;</code></pre><pre><code>&nbsp;&nbsp;&nbsp; std::list&lt;bus_stop *&gt; stops;</code></pre><pre><code>&nbsp;&nbsp;&nbsp; std::string driver_name;</code></pre><pre><code>&nbsp;&nbsp;&nbsp; template&lt;class Archive&gt;</code></pre><pre><code>&nbsp;&nbsp;&nbsp; void save(Archive &amp; ar, const unsigned int version) const</code></pre><pre><code>&nbsp;&nbsp;&nbsp; {</code></pre><pre><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // note, version is always the latest when saving</code></pre><pre><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ar&nbsp; &amp; driver_name;</code></pre><pre><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ar&nbsp; &amp; stops;</code></pre><pre><code>&nbsp;&nbsp;&nbsp; }</code></pre><pre><code>&nbsp;&nbsp;&nbsp; template&lt;class Archive&gt;</code></pre><pre><code>&nbsp;&nbsp;&nbsp; void load(Archive &amp; ar, const unsigned int version)</code></pre><pre><code>&nbsp;&nbsp;&nbsp; {</code></pre><pre><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(version &gt; 0)</code></pre><pre><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ar &amp; driver_name;</code></pre><pre><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ar&nbsp; &amp; stops;</code></pre><pre><code>&nbsp;&nbsp;&nbsp; }</code></pre><pre><code>&nbsp;&nbsp;&nbsp; BOOST_SERIALIZATION_SPLIT_MEMBER()</code></pre><pre><code>public:</code></pre><pre><code>&nbsp;&nbsp;&nbsp; bus_route(){}</code></pre><pre><code>};</code></pre><pre><code>&nbsp;</code></pre><pre><code>BOOST_CLASS_VERSION(bus_route, 1)</code></pre><pre>&nbsp;</pre>
<p>BOOST_SERIALIZATION_SPLIT_MEMBER() 宏生成调用 save 或 load的代码，依赖于是否档案被用于“存储”或“装载”。 
<p>&nbsp; <h5><a name="archives">档案</a></h5>
<p>我们这里讨论将聚焦到类的序列化能力上。被序列化的数据的实际编码实现于档案(archive)类中。被序列化的数据流是所选档案(archive)类的序列化的产物。(键)key设计决定这两个组件的独立性。允许任何序列化的规范可用于任何档案(archive)。
<p>在这篇指南中，我们用了一个档案类-用于存储的text_oarchive和用于装载的text_iarchive类。在库中其他档案类的接口完全一致。一旦类的序列化已经被定义，类能被序列化到任何档案类型。
<p>假如当前的档案集不能提供某个属性，格式，或行为需要特化的应用。要么创建一个新的要么从已有的里面衍生一个。将在后继文档中描述。
<p>注意我们的例子save和load程序数据在一个程序中，这是为了讨论方便而已。通常，被装载的档案或许在或许不在同一个程序中。
<p>T完整的演示程序 - <a href="http://www.boost.org/libs/serialization/example/demo.cpp">demo.cpp</a> 包括：
<ol>
<li>创建各种类别的 stops, routes 和 schedules 
<li>显示它 
<li>序列化到一个名叫 "testfile.txt"的文件中
<li>还原到另一个结构中 
<li>显示被存储的结构 </li></ol>
<p><a href="http://www.boost.org/libs/serialization/example/demo_output.txt">这个程序的输出</a> 分证实了对序列化系统所有的要求，都在这个系统中体现了。对序列化文件是ASCII文本的<a href="http://www.boost.org/libs/serialization/example/demofile.txt">档案文件的内容</a> 能被显示。</p><img src ="http://www.cppblog.com/woaidongmao/aggbug/64345.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/woaidongmao/" target="_blank">肥仔</a> 2008-10-19 00:38 <a href="http://www.cppblog.com/woaidongmao/archive/2008/10/19/64345.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>使用std::vector的一个误区</title><link>http://www.cppblog.com/woaidongmao/archive/2008/10/16/64134.html</link><dc:creator>肥仔</dc:creator><author>肥仔</author><pubDate>Thu, 16 Oct 2008 05:28:00 GMT</pubDate><guid>http://www.cppblog.com/woaidongmao/archive/2008/10/16/64134.html</guid><wfw:comment>http://www.cppblog.com/woaidongmao/comments/64134.html</wfw:comment><comments>http://www.cppblog.com/woaidongmao/archive/2008/10/16/64134.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/woaidongmao/comments/commentRss/64134.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/woaidongmao/services/trackbacks/64134.html</trackback:ping><description><![CDATA[<form id="Form1" name="Form1" action="http://www.cppblog.com/1010.html" method="post" _initialAction="1010.html"> <div class="pagelayout"> <div class="centercolumn"> <div class="singlepost">借助valgrind，终于找到一个隐藏很久的bug：<br> <div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align="top"><span style="color: #0000ff">class</span><span style="color: #000000"> A<br><img id="Codehighlighter1_8_21_Open_Image" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align="top"><img id="Codehighlighter1_8_21_Closed_Image" style="display: none" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align="top"></span><span id="Codehighlighter1_8_21_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"></span><span id="Codehighlighter1_8_21_Open_Text"><span style="color: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align="top">&nbsp;&nbsp;&nbsp; <img src="http://www.cppblog.com/Images/dot.gif"><img src="http://www.cppblog.com/Images/dot.gif"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align="top">}</span></span><span style="color: #000000">;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align="top">std::vector</span><span style="color: #000000">&lt;</span><span style="color: #000000">A</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp; vecArray;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align="top"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align="top">vecArray.push_back( <img src="http://www.cppblog.com/Images/dot.gif"> );<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align="top">vecArray.push_back( <img src="http://www.cppblog.com/Images/dot.gif"> );<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align="top">vecArray.push_back( <img src="http://www.cppblog.com/Images/dot.gif"> );<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align="top"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align="top">A </span><span style="color: #000000">&amp;</span><span style="color: #000000"> a</span><span style="color: #000000">=</span><span style="color: #000000"> vecArray.back();<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align="top">vecArray.push_back( <img src="http://www.cppblog.com/Images/dot.gif"> );<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align="top"><img src="http://www.cppblog.com/Images/dot.gif"><img src="http://www.cppblog.com/Images/dot.gif"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align="top"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align="top"></span></div>以上的代码骤眼看上去也没有什么奇怪的地方，经过多次的测试也没有发现什么问题。但昨天bug终于爆发了，程序总是无缘无故down掉。<br>其实原因很简单，就是在 A &amp; a = vecArray.back(); 这一步。<br>vector是一个会自增长的容器，自增长的结果就是把原来的内存释放掉，重新分配一个足够大的内存。既然原来的内存已经释放掉，那么a所引用的内存就是一段无效的内存。对无效内存的访问，后果有多严重就不用多说了。<br><br>想解决方法也很多，最简单就是用std::list或者std::deque替代vector。 </div> <div class="singlepost">&nbsp;</div> <div class="singlepost">========================================================================================</div> <div class="singlepost">&nbsp;</div> <p>Comments  <ul> <li> <p><a href="http://www.cppblog.com/cyt/archive/2005/11/10/1010.html#1026">#</a> <a name="1026"></a>re: 使用std::vector的一个误区  <p><a>glacjay</a><br>Posted @ 2005-11-09 22:06<br>不可以保存索引吗？必须要用指针吗？为了效率？&nbsp; <a href="http://www.cppblog.com/cyt/archive/2005/11/10/1010.html#post">回复</a> <a href="http://www.cppblog.com/comment?author=glacjay">更多评论</a> <a href="http://www.cppblog.com/"></a><a></a></p> <li> <p><a href="http://www.cppblog.com/cyt/archive/2005/11/10/1010.html#1033">#</a> <a name="1033"></a>re: 使用std::vector的一个误区  <p><a href="http://www.cppblog.com/cyt/">cyt</a><br>Posted @ 2005-11-10 09:23<br>用索引是可以，不过个人不大喜欢用索引。其原因就是索引并不是stl容器所共有的特性，一旦使用了索引，以后如果需要转换为其他容器的时候，未免需要改动不少地方。另外，我这里所说的只是一种解决方法。对于我这种情况，只需要更改一个typedef定义就可以解决问题。如果改成是用索引的话，需要更改不少地方，而且很容易会漏了。 <br>程序本身算法也比较复杂，相对来说使用索引性能也不会下降多少，这个倒不是什么需要考虑的地方了。&nbsp; <a href="http://www.cppblog.com/cyt/archive/2005/11/10/1010.html#post">回复</a> <a href="http://www.cppblog.com/comment?author=cyt">更多评论</a> <a href="http://www.cppblog.com/"></a><a></a></p> <li> <p><a href="http://www.cppblog.com/cyt/archive/2005/11/10/1010.html#1092">#</a> <a name="1092"></a>re: 使用std::vector的一个误区  <p><a>nilaozi</a><br>Posted @ 2005-11-11 22:23<br>最后一次评论。也够出气了！ <br>一个在blogjava失去家园的人声讨。 <br>除了政治原因可以删了一个人blog，别的理由都不能成为理由。 <br>我为每个都到他们所需的ebook难道错了， <br>贴到首页，我还以你们有预申机制，CSDN是这样，管理员认为可以才放到首页。 <br>不信你到他们的首页看看。 <br><a href="http://csdn.blog.net/ahhoo">http://csdn.blog.net/ahhoo</a><br>如果你认为还不错的，请到回贴。 <br><a href="http://www.cppblog.com/cyt/archive/2005/11/10/1010.html#post">回复</a> <a href="http://www.cppblog.com/comment?author=nilaozi">更多评论</a> <a href="http://www.cppblog.com/"></a><a></a></p> <li> <p><a href="http://www.cppblog.com/cyt/archive/2005/11/10/1010.html#12011">#</a> <a name="12011"></a>re: 使用std::vector的一个误区  <p><a href="http://www.cppblog.com/pjqblues/">blues</a><br>Posted @ 2006-09-04 14:05<br>vector和deque的差别是操作上的，list虽然是基于链表的，但是不能随机访问，任何的容器都不是完美的，而且使用指针必然要判断，但也算是个bug， <br>我想解决的话类型用boost的any应该可以了，它本身带有安全检查，我没试仅是建议&nbsp; <a href="http://www.cppblog.com/cyt/archive/2005/11/10/1010.html#post">回复</a> <a href="http://www.cppblog.com/comment?author=blues">更多评论</a> <a href="http://www.cppblog.com/"></a><a></a></p> <li> <p><a href="http://www.cppblog.com/cyt/archive/2005/11/10/1010.html#63290">#</a> <a name="63290"></a>re: 使用std::vector的一个误区<a name="Post"></a> <p><a>stl</a><br>Posted @ 2008-10-06 01:03<br>STL里的容器大部分都是“值”容器，你用“引用”去访问容器里的内容，错了正常。这不是vector的问题，你自己使用的问题。如果基于性能考虑上面的程序一定要使用“引用”语意的话，应该用vector&lt;A*&gt;的写法才比较正确。&nbsp; <a href="http://www.cppblog.com/cyt/archive/2005/11/10/1010.html#post">回复</a> <a href="http://www.cppblog.com/comment?author=stl">更多评论</a> <a href="http://www.cppblog.com/"></a></p></li></ul></div></div></form><img src ="http://www.cppblog.com/woaidongmao/aggbug/64134.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/woaidongmao/" target="_blank">肥仔</a> 2008-10-16 13:28 <a href="http://www.cppblog.com/woaidongmao/archive/2008/10/16/64134.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>iterator对数值加减的分别</title><link>http://www.cppblog.com/woaidongmao/archive/2008/10/13/63875.html</link><dc:creator>肥仔</dc:creator><author>肥仔</author><pubDate>Mon, 13 Oct 2008 03:25:00 GMT</pubDate><guid>http://www.cppblog.com/woaidongmao/archive/2008/10/13/63875.html</guid><wfw:comment>http://www.cppblog.com/woaidongmao/comments/63875.html</wfw:comment><comments>http://www.cppblog.com/woaidongmao/archive/2008/10/13/63875.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/woaidongmao/comments/commentRss/63875.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/woaidongmao/services/trackbacks/63875.html</trackback:ping><description><![CDATA[<p>//----下面的可以 <p>vector&lt;TickValue&gt;::iterator iter;<br>iter = iter + 3;&nbsp;&nbsp;&nbsp; <p>//----下面的不可以  <p>list&lt;TickValue&gt;::iterator iter;<br>iter = iter + 3;&nbsp;&nbsp;&nbsp; </p><img src ="http://www.cppblog.com/woaidongmao/aggbug/63875.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/woaidongmao/" target="_blank">肥仔</a> 2008-10-13 11:25 <a href="http://www.cppblog.com/woaidongmao/archive/2008/10/13/63875.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>STL的container的一些特性测试</title><link>http://www.cppblog.com/woaidongmao/archive/2008/09/09/61382.html</link><dc:creator>肥仔</dc:creator><author>肥仔</author><pubDate>Tue, 09 Sep 2008 07:53:00 GMT</pubDate><guid>http://www.cppblog.com/woaidongmao/archive/2008/09/09/61382.html</guid><wfw:comment>http://www.cppblog.com/woaidongmao/comments/61382.html</wfw:comment><comments>http://www.cppblog.com/woaidongmao/archive/2008/09/09/61382.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/woaidongmao/comments/commentRss/61382.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/woaidongmao/services/trackbacks/61382.html</trackback:ping><description><![CDATA[<p>空容器对首元素求地址运算 <p>int main(int argc, char* argv[])<br>{<br>&nbsp;&nbsp;&nbsp; vector&lt;int&gt; vec_test;<br>&nbsp;&nbsp;&nbsp; list&lt;int&gt;&nbsp;&nbsp;&nbsp; lst_test;<br>&nbsp;&nbsp;&nbsp; set&lt;int&gt;&nbsp;&nbsp;&nbsp; set_test;<br>&nbsp;&nbsp;&nbsp; int* p_test = &amp;(*vec_test.begin()); //---- NULL<br>&nbsp;&nbsp;&nbsp; p_test = &amp;vec_test[0];&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //---- NULL<br>&nbsp;&nbsp;&nbsp; p_test = &amp;(*lst_test.begin());&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //---- 不是NULL<br>&nbsp;&nbsp;&nbsp; p_test = (int*)&amp;(*set_test.begin());//---- 不是NULL<br>&nbsp;&nbsp;&nbsp; return 0;<br>} <p>============================================================================================ <p>vector的assgin空地址测试，红色部分无法理解 <p>int main(int argc, char* argv[])<br>{<br>&nbsp;&nbsp;&nbsp; vector&lt;int&gt; vec_test;<br>&nbsp;&nbsp;&nbsp; size_t s = 0;<br>&nbsp;&nbsp;&nbsp; vec_test.assign(NULL, NULL);<br>&nbsp;&nbsp;&nbsp; s = vec_test.size();&nbsp;&nbsp;&nbsp; //---- 0<br>&nbsp;<font color="#ff0000">&nbsp;&nbsp; vec_test.assign(NULL, NULL + 100);<br>&nbsp;&nbsp;&nbsp; s = vec_test.size();&nbsp;&nbsp;&nbsp; //---- 0</font><br>&nbsp;&nbsp;&nbsp; return 0;<br>}</p><img src ="http://www.cppblog.com/woaidongmao/aggbug/61382.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/woaidongmao/" target="_blank">肥仔</a> 2008-09-09 15:53 <a href="http://www.cppblog.com/woaidongmao/archive/2008/09/09/61382.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>容器.size()返回size_t，的注意事项</title><link>http://www.cppblog.com/woaidongmao/archive/2008/09/09/61380.html</link><dc:creator>肥仔</dc:creator><author>肥仔</author><pubDate>Tue, 09 Sep 2008 07:26:00 GMT</pubDate><guid>http://www.cppblog.com/woaidongmao/archive/2008/09/09/61380.html</guid><wfw:comment>http://www.cppblog.com/woaidongmao/comments/61380.html</wfw:comment><comments>http://www.cppblog.com/woaidongmao/archive/2008/09/09/61380.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/woaidongmao/comments/commentRss/61380.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/woaidongmao/services/trackbacks/61380.html</trackback:ping><description><![CDATA[<p>下面代码的原意是便利vector的前n-1个，但是，没注意到size_t是unsigned int，因此会出现bug.</p> <p>如果m_vecSymbolSummary.size() == 0,那么m_vecSymbolSummary.size() - 1将会变成很大数，而产生问题</p> <p>&nbsp;</p> <p><font color="#ff0000">for (size_t t = 0; t &lt; (m_vecSymbolSummary.size() - 1); ++t)</font></p><img src ="http://www.cppblog.com/woaidongmao/aggbug/61380.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/woaidongmao/" target="_blank">肥仔</a> 2008-09-09 15:26 <a href="http://www.cppblog.com/woaidongmao/archive/2008/09/09/61380.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>容器相等，可进行直接判断</title><link>http://www.cppblog.com/woaidongmao/archive/2008/09/06/61131.html</link><dc:creator>肥仔</dc:creator><author>肥仔</author><pubDate>Sat, 06 Sep 2008 08:37:00 GMT</pubDate><guid>http://www.cppblog.com/woaidongmao/archive/2008/09/06/61131.html</guid><wfw:comment>http://www.cppblog.com/woaidongmao/comments/61131.html</wfw:comment><comments>http://www.cppblog.com/woaidongmao/archive/2008/09/06/61131.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/woaidongmao/comments/commentRss/61131.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/woaidongmao/services/trackbacks/61131.html</trackback:ping><description><![CDATA[<p>vector, list, set, map ,hash_map, hash_set</p> <p>但是需要容器元素，支持==,或者有&lt;</p><img src ="http://www.cppblog.com/woaidongmao/aggbug/61131.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/woaidongmao/" target="_blank">肥仔</a> 2008-09-06 16:37 <a href="http://www.cppblog.com/woaidongmao/archive/2008/09/06/61131.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>std::sort多关键字排序</title><link>http://www.cppblog.com/woaidongmao/archive/2008/09/06/61126.html</link><dc:creator>肥仔</dc:creator><author>肥仔</author><pubDate>Sat, 06 Sep 2008 07:39:00 GMT</pubDate><guid>http://www.cppblog.com/woaidongmao/archive/2008/09/06/61126.html</guid><wfw:comment>http://www.cppblog.com/woaidongmao/comments/61126.html</wfw:comment><comments>http://www.cppblog.com/woaidongmao/archive/2008/09/06/61126.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/woaidongmao/comments/commentRss/61126.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/woaidongmao/services/trackbacks/61126.html</trackback:ping><description><![CDATA[<p>#include "stdafx.h"<br>#include &lt;stdlib.h&gt;<br>#include &lt;iostream&gt;<br>#include &lt;vector&gt;<br>#include &lt;algorithm&gt;<br>using namespace std;
<p>struct MultiData <br>{<br>&nbsp;&nbsp;&nbsp; int a;<br>&nbsp;&nbsp;&nbsp; int b;<br>&nbsp;&nbsp;&nbsp;int c;<br>};
<p><font color=#ff0000>struct ICmpMuls <br>{<br>&nbsp;&nbsp;&nbsp; bool operator()(const MultiData&amp; first, const MultiData&amp; second) const<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(first.a&lt; second.a)return true;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(first.a== second.a)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(first.b&lt; second.b)return true;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(first.b== second.b)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(first.c&lt; second.c)return true;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return false;<br>&nbsp;&nbsp;&nbsp; }<br>};</font>
<p>int main(int argc, char* argv[])<br>{<br>&nbsp;&nbsp;&nbsp; vector&lt;MultiData&gt; vec_muls;<br>&nbsp;&nbsp;&nbsp; for (int i = 0; i &lt; 300; ++i)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; vec_muls.push_back(MultiData(rand()%20, rand()));<br>&nbsp;&nbsp;&nbsp; sort(vec_muls.begin(), vec_muls.end(), ICmpMuls());<br>&nbsp;&nbsp;&nbsp; for (size_t s = 0; s &lt; vec_muls.size(); ++s)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cout&lt;&lt;s&lt;&lt;":&nbsp;&nbsp;&nbsp;&nbsp; "&lt;&lt;vec_muls[s].login&lt;&lt;" / "&lt;&lt;vec_muls[s].order&lt;&lt;endl;<br>&nbsp;&nbsp;&nbsp; return 0;<br>}</p>
<img src ="http://www.cppblog.com/woaidongmao/aggbug/61126.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/woaidongmao/" target="_blank">肥仔</a> 2008-09-06 15:39 <a href="http://www.cppblog.com/woaidongmao/archive/2008/09/06/61126.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>条款9：在删除选项中仔细选择</title><link>http://www.cppblog.com/woaidongmao/archive/2008/08/02/57844.html</link><dc:creator>肥仔</dc:creator><author>肥仔</author><pubDate>Sat, 02 Aug 2008 08:57:00 GMT</pubDate><guid>http://www.cppblog.com/woaidongmao/archive/2008/08/02/57844.html</guid><wfw:comment>http://www.cppblog.com/woaidongmao/comments/57844.html</wfw:comment><comments>http://www.cppblog.com/woaidongmao/archive/2008/08/02/57844.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/woaidongmao/comments/commentRss/57844.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/woaidongmao/services/trackbacks/57844.html</trackback:ping><description><![CDATA[<p>假定你有一个标准STL容器，c，容纳int，<pre>Container&lt;int&gt; c; </pre>
<p>而你想把c中所有值为1963的对象都去掉。令人吃惊的是，完成这项任务的方法因不同的容器类型而不同：没有一种方法是通用的。
<p>如果你有一个连续内存容器（vector、deque或string——参见<a href="http://www.stlchina.org/item_01.html">条款1</a>），最好的方法是erase-remove惯用法（参见<a href="http://www.stlchina.org/item_32.html">条款32</a>）：<pre>c.erase(remove(c.begin(), c.end(), 1963),	// 当c是vector、string
		c.end());			// 或deque时，
						// erase-remove惯用法
						// 是去除特定值的元素
						// 的最佳方法
</pre>
<p>这方法也适合于list，但是，正如<a href="http://www.stlchina.org/item_44.html">条款44</a>解释的，list的成员函数remove更高效：<pre>c.remove(1963);		// 当c是list时，
			// remove成员函数是去除
			// 特定值的元素的最佳方法
</pre>
<p>当c是标准关联容器（即，set、multiset、map或multimap）时，使用任何叫做remove的东西都是完全错误的。这样的容器没有叫做remove的成员函数，而且使用remove算法可能覆盖容器值（参见<a href="http://www.stlchina.org/item_32.html">条款32</a>），潜在地破坏容器。（关于这样的破坏的细节，参考<a href="http://www.stlchina.org/item_22.html">条款22</a>，那个条款也解释了为什么试图在map和multimap上使用remove肯定不能编译，而试图在set和multiset上使用可能不能编译。）
<p>不，对于关联容器，解决问题的适当方法是调用erase：<pre>c.erase(1963);		// 当c是标准关联容器时
			// erase成员函数是去除
			// 特定值的元素的最佳方法
</pre>
<p>这不仅是正确的，而且很高效，只花费对数时间。（序列容器的基于删除的技术需要线性时间。）并且，关联容器的erase成员函数有基于等价而不是相等的优势，<a href="http://www.stlchina.org/item_19.html">条款19</a>解释了这一区别的重要性。
<p>让我们现在稍微修改一下这个问题。不是从c中除去每个有特定值的物体，让我们消除下面判断式（参见<a href="http://www.stlchina.org/item_39.html">条款39</a>）返回真的每个对象：<pre>bool badValue(int x);	// 返回x是否是“bad”</pre>
<p>对于序列容器（vector、string、deque和list），我们要做的只是把每个remove替换为remove_if，然后就完成了：<pre>c.erase(remove_if(c.begin(), c.end(), badValue),	// 当c是vector、string
			c.end());			// 或deque时这是去掉
						// badValue返回真
						// 的对象的最佳方法
c.remove_if(badValue);				// 当c是list时这是去掉
						// badValue返回真
						// 的对象的最佳方法
</pre>
<p>对于标准关联容器，它不是很直截了当。有两种方法处理该问题，一个更容易编码，另一个更高效。“更容易但效率较低”的解决方案用remove_copy_if把我们需要的值拷贝到一个新容器中，然后把原容器的内容和新的交换：<pre><var>AssocContainer</var>&lt;int&gt; c;				// c现在是一种
...						// 标准关联容器
<var>AssocContainer</var>&lt;int&gt; goodValues;			// 用于容纳不删除
						// 的值的临时容器
remove_copy_if(c.begin(), c.end(),			// 从c拷贝不删除
		inserter(goodValues,		// 的值到
			goodValues.end()),		// goodValues
			badValue);
c.swap(goodValues);				// 交换c和goodValues
						// 的内容
</pre>
<p>对这种方法的缺点是它拷贝了所有不删除的元素，而这样的拷贝开销可能大于我们感兴趣支付的。
<p>我们可以通过直接从原容器删除元素来避开那笔帐单。不过，因为关联容器没有提供类似remove_if的成员函数，所以我们必须写一个循环来迭代c中的元素，和原来一样删除元素。
<p>看起来，这个任务很简单，而且实际上，代码也很简单。不幸的是，那些正确工作的代码很少是跃出脑海的代码。例如，这是很多程序员首先想到的：<pre><var>AssocContainer</var>&lt;int&gt; c;
...
for (<var>AssocContainer</var>&lt;int&gt;::iterator i = c.begin();	// 清晰，直截了当
		i!= c.end();			// 而漏洞百出的用于
		++i) {				// 删除c中badValue返回真
	if (badValue(*i)) c.erase(i);		// 的每个元素的代码
}						// 不要这么做！
</pre>
<p>唉，这有未定义的行为。当容器的一个元素被删时，指向那个元素的所有迭代器都失效了。当c.erase(i)返回时，i已经失效。那对于这个循环是个坏消息，因为在erase返回后，i通过for循环的++i部分自增。
<p>为了避免这个问题，我们必须保证在调用erase之前就得到了c中下一元素的迭代器。最容易的方法是当我们调用时在i上使用后置递增：<pre><var>AssocContainer</var>&lt;int&gt; c;
...
for (<var>AssocContainer</var>&lt;int&gt;::iterator i = c.begin();	// for循环的第三部分
	i != c.end();				// 是空的；i现在在下面
	/*nothing*/ ){				// 自增
	if (badValue(*i)) c.erase(i++);		// 对于坏的值，把当前的
	else ++i;					// i传给erase，然后
}						// 作为副作用增加i；
						// 对于好的值，
						// 只增加i
</pre>
<p>这种调用erase的解决方法可以工作，因为表达式i++的值是i的旧值，但作为副作用，i增加了。因此，我们把i的旧值（没增加的）传给erase，但在erase开始执行前i已经自增了。那正好是我们想要的。正如我所说的，代码很简单，只不过不是大多数程序员在第一次尝试时想到的。
<p>现在让我们进一步修改该问题。不仅删除badValue返回真的每个元素，而且每当一个元素被删掉时，我们也想把一条消息写到日志文件中。
<p>对于关联容器，这说多容易就有多容易，因为只需要对我们刚才开发的循环做一个微不足道的修改就行了：<pre>ofstream logFile;					// 要写入的日志文件
<var>AssocContainer</var>&lt;int&gt; c;
...
for (<var>AssocContainer</var>&lt;int&gt;::iterator i = c.begin();	// 循环条件和前面一样
	i !=c.end();){
	if (badValue(*i)){ 
		logFile &lt;&lt; "Erasing " &lt;&lt; *i &lt;&lt;'\n';	// 写日志文件 
		c.erase(i++);			// 删除元素
	}
	else ++i;
}
</pre>
<p>现在是vector、string和deque给我们带来麻烦。我们不能再使用erase-remove惯用法，因为没有办法让erase或remove写日志文件。而且，我们不能使用刚刚为关联容器开发的循环，因为它为vector、string和deque产生未定义的行为！要记得对于那样的容器，调用erase不仅使所有指向被删元素的迭代器失效，也使被删元素<em>之后</em>的所有迭代器失效。在我们的情况里，那包括所有i之后的迭代器。我们写i++，++i或你能想起的其它任何东西都没有用，因为没有能导致迭代器有效的。
<p>我们必须对vector、string和deque采用不同的战略。特别是，我们必须利用erase的返回值。那个返回值正是我们需要的：一旦删除完成，它就是指向紧接在被删元素之后的元素的有效迭代器。换句话说，我们这么写：<pre>for (<var>SeqContainer</var>&lt;int&gt;::iterator i = c.begin(); 
	i != c.end();){
	if (badValue(*i)){
		logFile &lt;&lt; "Erasing " &lt;&lt; *i &lt;&lt; '\n'; 
		i = c.erase(i);			// 通过把erase的返回值
	}					// 赋给i来保持i有效
	else
		++i;
}
</pre>
<p>这可以很好地工作，但只用于标准序列容器。由于论证一个可能的问题（<a href="http://www.stlchina.org/item_05.html">条款5</a>做了），标准关联容器的erase的返回类型是void<sup><a href="http://www.stlchina.org/#Note1">[1]</a></sup>。对于那些容器，你必须使用“后置递增你要传给erase的迭代器”技术。（顺便说说，在为序列容器编码和为关联容器编码之间的这种差别是为什么写容器无关代码一般缺乏考虑的一个例子——参见<a href="http://www.stlchina.org/item_02.html">条款2</a>。)
<p>为了避免你奇怪list的适当方法是什么，事实表明对于迭代和删除，你可以像vector/string/deque一样或像关联容器一样对待list；两种方法都可以为list工作。
<p>如果我们观察在本条款中提到的所有东西，我们得出下列结论：
<ul>
<li><strong>去除一个容器中有特定值的所有对象：</strong>
<p>如果容器是vector、string或deque，使用erase-remove惯用法。
<p>如果容器是list，使用list::remove。
<p>如果容器是标准关联容器，使用它的erase成员函数。</p>
<li><strong>去除一个容器中满足一个特定判定式的所有对象：</strong>
<p>如果容器是vector、string或deque，使用erase-remove_if惯用法。
<p>如果容器是list，使用list::remove_if。
<p>如果容器是标准关联容器，使用remove_copy_if和swap，或写一个循环来遍历容器元素，当你把迭代器传给erase时记得后置递增它。</p>
<li><strong>在循环内做某些事情（除了删除对象之外）：</strong>
<p>如果容器是标准序列容器，写一个循环来遍历容器元素，每当调用erase时记得都用它的返回值更新你的迭代器。
<p>如果容器是标准关联容器，写一个循环来遍历容器元素，当你把迭代器传给erase时记得后置递增它。</p></li></ul>
<p>如你所见，与仅仅调用erase相比，有效地删除容器元素有更多的东西。解决问题的最好方法取决于你是怎样鉴别出哪个对象是要被去掉的，储存它们的容器的类型，和当你删除它们的时候你还想要做什么（如果有的话）。只要你小心而且注意了本条款的建议，你将毫不费力。如果你不小心，你将冒着产生不必要低效的代码或未定义行为的危险。</p><img src ="http://www.cppblog.com/woaidongmao/aggbug/57844.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/woaidongmao/" target="_blank">肥仔</a> 2008-08-02 16:57 <a href="http://www.cppblog.com/woaidongmao/archive/2008/08/02/57844.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>STL 查找算法</title><link>http://www.cppblog.com/woaidongmao/archive/2008/07/04/55335.html</link><dc:creator>肥仔</dc:creator><author>肥仔</author><pubDate>Fri, 04 Jul 2008 05:36:00 GMT</pubDate><guid>http://www.cppblog.com/woaidongmao/archive/2008/07/04/55335.html</guid><wfw:comment>http://www.cppblog.com/woaidongmao/comments/55335.html</wfw:comment><comments>http://www.cppblog.com/woaidongmao/archive/2008/07/04/55335.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/woaidongmao/comments/commentRss/55335.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/woaidongmao/services/trackbacks/55335.html</trackback:ping><description><![CDATA[<div id="csdnblog_allwrap"> <form language="javascript" id="Form1" name="Form1" action="http://blog.csdn.net/8055.aspx" method="post"> <div id="csdnblog_midwrap"> <div id="csdnblog_content"> <div class="gutter"> <div class="default_contents"> <div class="user_article"> <div class="blogstory"> <p>要给出所有我们在本条款中所考虑到的，我们的从哪儿着手？下面的表格道出了一切。</p> <table> <tbody> <tr> <th rowspan="2">你想知道的  <th colspan="2">使用的算法  <th colspan="2">使用的成员函数</tr>  <tr> <td>在无序区间</td> <td>在已序区间</td> <td>在set或map上</td> <td>在multiset或multimap上</td></tr> <tr> <td>期望值是否存在？</td> <td>find</td> <td>binary_search</td> <td>count</td> <td>find</td></tr> <tr> <td>期望值是否存在？如果有，第一个等于这个值的对象在哪里？</td> <td>find</td> <td>equal_range</td> <td>find</td> <td>find or lower_bound(see article)</td></tr> <tr> <td>第一个不等于期望值的对象在哪里？</td> <td>find_if</td> <td>lower_bound</td> <td>lower_bound</td> <td>lower_bound</td></tr> <tr> <td>第一个等于期望值的对象在哪里？</td> <td>find_if</td> <td>upper_bound</td> <td>upper_bound</td> <td>upper_bound</td></tr> <tr> <td>有多少对象等于期望值？</td> <td>count</td> <td>equal_range</td> <td>count</td> <td>count</td></tr> <tr> <td>等于期望值的所有对象在哪里？</td> <td>find（迭代）</td> <td>equal_range</td> <td>equal_range</td> <td>equal_range</td></tr></tbody></table></div></div></div></div></div></div></form></div> <h5>===============================================================================</h5> <h5>Example</h5><pre>// equal_range example
#include &lt;iostream&gt;
#include &lt;algorithm&gt;
#include &lt;vector&gt;
using namespace std;

bool mygreater (int i,int j) { return (i&gt;j); }

int main () {
  int myints[] = {10,20,30,30,20,10,10,20};
  vector&lt;int&gt; v(myints,myints+8);                         // 10 20 30 30 20 10 10 20
  pair&lt;vector&lt;int&gt;::iterator,vector&lt;int&gt;::iterator&gt; bounds;

  // using default comparison:
  sort (v.begin(), v.end());                              // 10 10 10 20 20 20 30 30
  bounds=equal_range (v.begin(), v.end(), 20);            //          ^        ^

  // using "mygreater" as comp:
  sort (v.begin(), v.end(), mygreater);                   // 30 30 20 20 20 10 10 10
  bounds=equal_range (v.begin(), v.end(), 20, mygreater); //       ^        ^

  cout &lt;&lt; "bounds at positions " &lt;&lt; int(bounds.first - v.begin());
  cout &lt;&lt; " and " &lt;&lt; int(bounds.second - v.begin()) &lt;&lt; endl;

  return 0;
}
</pre>
<p>Output:<pre><tt>bounds ar positions 2 and 5<br></tt></pre><pre><tt>=================================================================</tt></pre>
<p><a name="app01lev1sec10"></a>
<h5><tt>equal_range()</tt></h5><pre>template&lt; class ForwardIterator, class Type &gt;
pair&lt; ForwardIterator, ForwardIterator &gt;
equal_range( ForwardIterator first,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ForwardIterator last, const Type &amp;value );</pre><pre>//返回pair ，若容器中存在搜索值，第一个返回by <tt>lower_bound();</tt> 第二个 by <tt>upper_bound();</tt> </pre><pre>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 若容器中不存在搜索值，两个都返回by <tt>upper_bound();</tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; template&lt; class ForwardIterator, class Type, class Compare &gt;
pair&lt; ForwardIterator, ForwardIterator &gt;
equal_range( ForwardIterator first,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ForwardIterator last, const Type &amp;value,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Compare comp );
</pre>
<p>#include &lt;algorithm&gt;<br>#include &lt;vector&gt;<br>#include &lt;utility&gt;<br>#include &lt;iostream&gt;<br>#include&lt;functional&gt;<br>using namespace std;<br>/* generates:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; array element sequence after sort:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 12 15 17 19 20 22 23 26 29 35 40 51<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; equal_range result of search for value 23:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *ia_iter.first: 23&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *ia_iter.second: 26<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; equal_range result of search for absent value 21:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *ia_iter.first: 22&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *ia_iter.second: 22<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; vector element sequence after sort:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 51 40 35 29 26 23 22 20 19 17 15 12<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; equal_range result of search for value 26:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *ivec_iter.first: 26&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *ivec_iter.second: 23<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; equal_range result of search for absent value 21:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *ivec_iter.first: 20&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *ivec_iter.second: 20<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */
<p>int main()<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int ia[] = { 29,23,20,22,17,15,26,51,19,12,35,40 };<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; vector&lt; int &gt; ivec( ia, ia+12 );<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ostream_iterator&lt; int &gt;&nbsp;&nbsp;&nbsp;&nbsp; ofile( cout, " " );<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sort( &amp;ia[0], &amp;ia[12] );<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cout &lt;&lt; "array element sequence after sort:\n";<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; copy( ia, ia+12, ofile ); cout &lt;&lt; "\n\n";<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pair&lt; int*,int* &gt; ia_iter;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ia_iter = equal_range( &amp;ia[0], &amp;ia[12], 23 );<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cout &lt;&lt; "equal_range result of search for value 23:\n\t"<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;&lt; "*ia_iter.first: "&nbsp;&nbsp;&nbsp;&nbsp; &lt;&lt; *ia_iter.first &lt;&lt; "\t"<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;&lt; "*ia_iter.second: " &lt;&lt; *ia_iter.second &lt;&lt; "\n\n";<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ia_iter = equal_range( &amp;ia[0], &amp;ia[12], 21 );<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cout &lt;&lt; "equal_range result of search for "<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;&lt; "absent value 21:\n\t"<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;&lt; "*ia_iter.first: "&nbsp;&nbsp;&nbsp;&nbsp; &lt;&lt; *ia_iter.first &lt;&lt; "\t"<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;&lt; "*ia_iter.second: " &lt;&lt; *ia_iter.second &lt;&lt; "\n\n";<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sort( ivec.begin(), ivec.end(), greater&lt;int&gt;() );<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cout &lt;&lt; "vector element sequence after sort:\n";<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; copy( ivec.begin(), ivec.end(), ofile ); cout &lt;&lt; "\n\n";<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; typedef vector&lt; int&gt;::iterator iter_ivec;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pair&lt; iter_ivec, iter_ivec &gt; ivec_iter;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ivec_iter = equal_range( ivec.begin(), ivec.end(), 26,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; greater&lt;int&gt;() );<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cout &lt;&lt; "equal_range result of search for value 26:\n\t"<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;&lt; "*ivec_iter.first: "&nbsp;&nbsp;&nbsp;&nbsp; &lt;&lt; *ivec_iter.first &lt;&lt; "\t"<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;&lt; "*ivec_iter.second: " &lt;&lt; *ivec_iter.second<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ivec_iter = equal_range( ivec.begin(), ivec.end(), 21,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; greater&lt;int&gt;() );<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cout &lt;&lt; "equal_range result of search for "<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;&lt; "absent value 21:\n\t"<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;&lt; "*ivec_iter.first: "&nbsp;&nbsp;&nbsp;&nbsp; &lt;&lt; *ivec_iter.first &lt;&lt; "\t"<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;&lt; "*ivec_iter.second: " &lt;&lt; *ivec_iter.second<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ;<br>}</p><img src ="http://www.cppblog.com/woaidongmao/aggbug/55335.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/woaidongmao/" target="_blank">肥仔</a> 2008-07-04 13:36 <a href="http://www.cppblog.com/woaidongmao/archive/2008/07/04/55335.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>EffectiveSTL：Item16：如何将vector和string的数据传给传统的API函数</title><link>http://www.cppblog.com/woaidongmao/archive/2008/06/19/54027.html</link><dc:creator>肥仔</dc:creator><author>肥仔</author><pubDate>Thu, 19 Jun 2008 08:13:00 GMT</pubDate><guid>http://www.cppblog.com/woaidongmao/archive/2008/06/19/54027.html</guid><wfw:comment>http://www.cppblog.com/woaidongmao/comments/54027.html</wfw:comment><comments>http://www.cppblog.com/woaidongmao/archive/2008/06/19/54027.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/woaidongmao/comments/commentRss/54027.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/woaidongmao/services/trackbacks/54027.html</trackback:ping><description><![CDATA[<p><b>Item 16：如何将vector和string的数据传给传统的API函数</b>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 因为 C++语言已经于1998年被标准化，C++的中坚分子在试图推动程序员从数组转到vector时就没什么顾虑了。同样的情况也发生于从char *指针转到string对象的过程中。有很好的理由来做这些转变，比如可以消除常见的编程错误（Item 13），和有机会获得STL泛型算法的全部强大能力 (参见，比如，Item 31)。  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 但是，麻烦还是有的，而最常见的一个就是已经存在的传统C风格API函数接受的是数组和char *指针，而不是vector和string对象。这样的API函数还将会存在很长时间，如果我们要高效使用STL的话，就必须和它们和平共处。  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 幸运的是，这很容易。如果你有一个vector对象v，而你需要得到一个指向v中数据的指针，以使得它可以被当作一个数组，只要使用&amp;v[0]就可以了。对于string对象s，相应的语法是很简单的s.c_str()。但只能从上面读。如广告时常指明的，有几个限制。。  <p>给定一个  <p>vector&lt;int&gt; v;  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 表达式v[0]生产一个指向vector中首元素的引用，所以，&amp;v[0]是指向那个首元素的指针。vector中的元素被C++标准限定为存储在连续内存中，就象是一个数组，所以，如果我们传递v给如此形式的C风格API函数  <p>void doSomething(const int* pInts, size_t numInts);  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 我们可以这么做：  <p>doSomething(&amp;v[0],v.size());  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 也许吧。可能吧。唯一的问题就是，如果v是空的。如果这样的话，v.size()是0，而&amp;v[0]试图产生一个指向根本就不存在的东西的指针。这不是件好事。其结果未定义。一个较安全的方法是这样：  <p>if (!v.empty()) {  <p>doSomething(&amp;v[0], v.size());  <p>}  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 如果走得不对路，你可能会碰到些半瓶子的人物，他们会告诉你说可以用v.begin()代替&amp;v[0]，因为(这些讨厌的家伙将会告诉你)begin()返回指向vector内部的iterator，而对于vector，其iterators实际上是指针。那经常是正确的，但如Item 50所说，并不总是如此，你不该依赖于此。begin()的返回类型是iterator，而不是一个指针，当你需要一个指向vector内部数据的指针时绝不该使用begin()。如果你基于某些原因决定键入v.begin()，就键入&amp;*v.begin()， 因为这将会产生和&amp;v[0]相同的指针，虽然它让你有更多的击键工作且让代码读起来更晦涩。坦白地说，如果你正被告诉你使用v.begin()代替&amp;v[0]的人围绕的话，你该重新考虑一下你的社交圈了。  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 类似的从vector上获取指向内部数据的指针的方法，对string是不可靠的，因为 <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (1) string中的数据并没有承诺被存储在连续内存中， <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (2)string的内部表示形式并没承诺以一个空字符结束。 <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 这解释了string的成员函数c_str()存在的原因，它返回一个按C风格设计指针，指向string的值（which returns a pointer to the value of the string in a form designed for C）。 我们可以如此传递一个string对象s给这个函数，  <p>void doSomething(const char *pString);  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 就象这样：  <p>doSomething(s.c_str());  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 即使是字符串的长度为0，它都能工作。在那种情况下，c_str()将返回一个指向结束符的指针。即使字符串内部自己存在结束符时，它同样能工作。然而，如果真的这样，doSomething很可能将第一个结束符解释为字符串结束。string对象不在意是否容纳了结束符，但基于char *的C风格API函数在意。  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 再看一下doSomething()的申明：  <p>void doSomething(const int* pInts, size_t numInts);  <p>void doSomething(const char *pString);  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 在两种形式下，指针都被传递为指向const的指针。vector和string的数据被传给只读取而不修改它们的API函数。到目前为止都做的是最安全的事情。对于string，这也是唯一可做的，因为没有承诺说c_str()产生的指针指在string数据的内部表示形式上；它可以返回一个指针指向数据的一个不可修改的拷贝，这个拷贝满足C风格API函数对格式的要求。（如果这个恐吓令你寒毛都立起来的话，还请宽心，因为它也许不成立。我没听说目前哪个运行库的实现是使用了这个自由权的。）  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 对于vector，有更多一点点灵活性。如果你将v传给一个修改其元素的C风格API函数的话，典型情况都是没问题，但被调用的函数绝不能试图改变vector中元素的个数。比如，它绝不能试图在vector还未使用的容量（capacity）上“创建”新的元素。如果这么干了，v将会变得内部状态不一致，因为它再也不知道自己的正确大小（size）了。v.size()将会得到一个不正确的结果。并且，如果被调用的函数试图在一个大小和容量（见Item 14）相等的vector上追加数据的话，真的会发生灾难性事件。我甚至根本就不愿去想象它。实在太可怕了。  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 你注意到我在前面用的是“典型地”一词吗？你当然注意到了。有些vector对其数据有些额外的限制，你一定要确保这些额外限制继续被满足。举个例子，Item 23解释了排序的vector常用来实现关联容器，但对这些vector而言，保持排序非常重要。如果你将一个排序的vector传给一个可能修改其数据的API函数，你需要重视vector在调用返回后不再保持排序的情况。  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 如果你想用C风格API函数返回的元素初始化一个vector，你可以利用vector和数组内在的相容性，通过将存储vecotr的元素的空间传给API函数：  <p>// C API: this function takes a pointer to an array of at most arraySize  <p>// doubles and writes data to it. It returns the number of doubles written,  <p>// which is never more than maxNumDoubles.  <p>size_t fillArray(double *pArray, size_t arraySize);  <p>vector&lt;double&gt; vd(maxNumDoubles); // create a vector whose  <p>// size is maxNumDoubles  <p>vd.resize(fillArray(&amp;vd[0], vd.size())); // have fillArray write data  <p>// into vd, then resize vd  <p>// to the number of  <p>// elements fillArray wrote  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 这个技巧只能工作于vector，因为只有vector承诺了与数组具有相同的内在内存分布。但是，如果你想用来自C风格API函数的数据初始化string对象，你可以做得足够简单。只要让API函数将数据放入一个vector&lt;char&gt;，然后从vector中将数据拷到string:  <p>// C API: this function takes a pointer to an array of at most arraySize  <p>// chars and writes data to it. It returns the number of chars written,  <p>// which is never more than maxNumChars.  <p>size_t fillString(char *pArray, size_t arraySize);  <p>vector&lt;char&gt; vc(maxNumChars); // create a vector whose  <p>// size is maxNumChars  <p>size_t charsWritten = fillString(&amp;vc[0], vc.size()); // have fillString write  <p>// into vc  <p>string s(vc.begin(), vc.begin()+charsWritten); // copy data from vc to s  <p>// via range constructor  <p>// ( see Item 5)  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 事实上，这个主意总是有效的：让C风格API函数将数据放入一个vector，然后拷到你实际想要的STL容器中。  <p>size_t fillArray(double *pArray, size_t arraySize); // as above  <p>vector&lt;double&gt; vd(maxNumDoubles); // also as above  <p>vd.resize(fillArray(&amp;vd[0], vd.size());  <p>deque&lt;double&gt; d(vd.begin(), vd.end()); // copy data into  <p>// deque  <p>list&lt;double&gt; l(vd.begin(), vd.end()); // copy data into list  <p>set&lt;double&gt; s(vd.begin(), vd.end()); // copy data into set  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 此外，这也提示了vector和string以外的STL容器如何将它们的数据传给C风格API函数。只要将容器的每个数据拷到vector，然后将它们传给API函数：  <p>void doSomething(const int* pInts, size_t numInts); // C API (from above)  <p>set&lt;int&gt; intSet; // set that will hold  <p>... // data to pass to API  <p>vector&lt;int&gt; v(intSet.begin(), intSet.end()); // copy set data into  <p>// a vector  <p>if (!v.empty()) doSomething(&amp;v[0], v.size()); // pass the data to  <p>// the API  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 你也可以将数据拷进一个数组，然后将数组传给C风格的API，但你为什么想这样做？除非你在编译期就知道容器的大小，否则你不得不分配动态数组，而Item 13解释了为什么你应该总是使用vector来取代动态分配的数组。  <img src ="http://www.cppblog.com/woaidongmao/aggbug/54027.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/woaidongmao/" target="_blank">肥仔</a> 2008-06-19 16:13 <a href="http://www.cppblog.com/woaidongmao/archive/2008/06/19/54027.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>使用boost.spirit制作一个简单的四则计算器</title><link>http://www.cppblog.com/woaidongmao/archive/2008/05/17/50116.html</link><dc:creator>肥仔</dc:creator><author>肥仔</author><pubDate>Fri, 16 May 2008 16:16:00 GMT</pubDate><guid>http://www.cppblog.com/woaidongmao/archive/2008/05/17/50116.html</guid><wfw:comment>http://www.cppblog.com/woaidongmao/comments/50116.html</wfw:comment><comments>http://www.cppblog.com/woaidongmao/archive/2008/05/17/50116.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/woaidongmao/comments/commentRss/50116.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/woaidongmao/services/trackbacks/50116.html</trackback:ping><description><![CDATA[<p></p> <div id="page"> <div class="narrowcolumn" id="main"> <div id="contents" style="margin-right: 260px"> <div class="llist1"> <div class="padding6x"> <div class="post" id="post-4942"> <div class="content"> <div class="intro"> <div class="excerpt">　从传统意义上来说，boost.spirit库是一个类似于yacc的库，主要业务是做词法解析，然后提供各种读取数据的接口，但是由于这是一个用C++实现、并且大量运Expression Templates技巧的库... </div></div> <div class="tbody">点击下载此文件：<img style="margin: 0px 2px -4px 0px" alt="下载文件" src="http://www.kuqin.com/upimg/allimg/070913/0001320.gif"> <a href="http://www.kuqin.com/smalldoc/w20075422294.rar" target="_blank">简单的四则计算器源码和可执行程序</a><br><br>从传统意义上来说，boost.spirit库是一个类似于yacc的库，主要业务是做词法解析，然后提供各种读取数据的接口，但是由于这是一个用C++实现、并且大量运<a href="http://ubiety.uwaterloo.ca/~tveldhui/papers/Expression-Templates/exprtmpl.html" target="_blank">Expression Templates</a>技巧的库，所以各种功能可以用非常快捷的方式实现，非常的好用，几乎把C++的各种优良特性都充分发挥出来。<br><br>在此，我就从boost.spirit库中间的一个例子出发，经过简单的修改就变成一个极为健壮的四则计算器。我所参考的例子是boost 1.34.0的libs/spirit/example/fundamental/calc_plain.cpp，我因为是在这上面直接修改而来，所以源码中带有原作者的版权声明。<br><br>关于boost.spirit的用法，在这里我先不说，以后有时间我来慢慢的把它用中国话讲解一遍。这个程序的核心实际上是一个EBNF的表达式，也就是如何用EBNF语法来表示四则运算。<br>在这里，我就直接给出答案（EBNF的知识请暂时自行看编译原理的教材）：<br> <div class="UBBPanel"> <div class="UBBTitle"><img style="margin: 0px 2px -3px 0px" alt="程序代码" src="http://www.kuqin.com/upimg/allimg/070913/0001321.gif"> 程序代码</div> <div class="UBBContent"><br>expression ::= term ( ('+' term) | ('-' term) )*<br>term ::= factor ( ('*' factor) | ('/' factor) )*<br>factor ::= REAL | '(' ex ')' | ('-' factor) | ('+' factor)<br></div></div><br>其中，expression就是我们需要的表达式pattern。注意这里，正是由于expression首先去匹配term，而term首先去匹配factor，最后factor是以“纯数字”、“括号”、“正负符号”的顺序匹配，term则是以factor、“乘法”、“除法”的顺序匹配，而expression是以term、“加法”、“减法”的顺序匹配，所以就保证了整个表达式匹配过程是按照四则运算的先后顺序进行的。在匹配的过程中只要安插各种“监视”的函数（boost.spirit里面的术语叫做“actor”），就可以轻松实现四则运算。<br><br>把EBNF对应到boost.spirit里，具体的grammer类实现如下：<br> <div class="UBBPanel"> <div class="UBBTitle"><img style="margin: 0px 2px -3px 0px" alt="程序代码" src="http://www.kuqin.com/upimg/allimg/070913/0001321.gif"> 程序代码</div> <div class="UBBContent">struct calculator : public grammar&lt;calculator&gt;<br>{<br>&nbsp;&nbsp;&nbsp; template &lt;typename ScannerT&gt;<br>&nbsp;&nbsp;&nbsp; struct definition<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; definition(calculator const&amp; /*self*/)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; expression<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; =&nbsp;&nbsp; term<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &gt;&gt; *(&nbsp;&nbsp; ('+' &gt;&gt; term[do_calc&lt;do_add&gt;()])<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |&nbsp;&nbsp; ('-' &gt;&gt; term[do_calc&lt;do_substract&gt;()])<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; )<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; term<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; =&nbsp;&nbsp; factor<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &gt;&gt; *(&nbsp;&nbsp; ('*' &gt;&gt; factor[do_calc&lt;do_multiply&gt;()])<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |&nbsp;&nbsp; ('/' &gt;&gt; factor[do_calc&lt;do_divide&gt;()])<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; )<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; factor<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; =&nbsp;&nbsp; real_p[&amp;push_real]<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |&nbsp;&nbsp; '(' &gt;&gt; expression &gt;&gt; ')'<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |&nbsp;&nbsp; ('-' &gt;&gt; factor[&amp;do_neg])<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |&nbsp;&nbsp; ('+' &gt;&gt; factor)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rule&lt;ScannerT&gt; expression, term, factor;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rule&lt;ScannerT&gt; const&amp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; start() const { return expression; }<br>&nbsp;&nbsp;&nbsp; };<br>};<br></div></div><br>请注意，calculator从grammer派生，但是除了在内部定义了一个嵌套class以外，并没有做更多的事情。<br><br>至于这里面用到的do_calc&lt;&gt;、push_real等functor和函数，则是一些极为简单的东西，实现如下：<br> <div class="UBBPanel"> <div class="UBBTitle"><img style="margin: 0px 2px -3px 0px" alt="程序代码" src="http://www.kuqin.com/upimg/allimg/070913/0001321.gif"> 程序代码</div> <div class="UBBContent">namespace<br>{<br>&nbsp;&nbsp;&nbsp; stack&lt;double&gt; calc_stack;<br><br>&nbsp;&nbsp;&nbsp; struct do_add<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; double operator () (double lhs, double rhs) const<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return lhs + rhs;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; };<br><br>&nbsp;&nbsp;&nbsp; struct do_substract<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; double operator () (double lhs, double rhs) const<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return lhs - rhs;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; };<br><br>&nbsp;&nbsp;&nbsp; struct do_multiply<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; double operator () (double lhs, double rhs) const<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return lhs * rhs;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; };<br><br>&nbsp;&nbsp;&nbsp; struct do_divide<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; double operator () (double lhs, double rhs) const<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return lhs / rhs;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; };<br><br>&nbsp;&nbsp;&nbsp; template &lt;typename op&gt;<br>&nbsp;&nbsp;&nbsp; struct do_calc<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; void operator () (const char *, const char *) const<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; double result = calc_stack.top();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; calc_stack.pop();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; result = op()(calc_stack.top(), result);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; calc_stack.pop();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; calc_stack.push(result);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; };<br><br>&nbsp;&nbsp;&nbsp; void push_real(double d)<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; calc_stack.push(d);<br>&nbsp;&nbsp;&nbsp; }<br><br>&nbsp;&nbsp;&nbsp; void do_neg(char const*, char const*)&nbsp; <br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cout &lt;&lt; "NEGATE\n";<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; double result = calc_stack.top();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; calc_stack.pop();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; calc_stack.push(-result);<br>&nbsp;&nbsp;&nbsp; }<br><br>&nbsp;&nbsp;&nbsp; double show_result()&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return calc_stack.top();<br>&nbsp;&nbsp;&nbsp; }<br>}<br></div></div> <p><br>可以从源码中清晰看到，这些函数就是简单的做了些出栈/入栈以及运算的工作，每一个函数功能极为单纯，可认为就是一些状态及处理函数而已，而状态机逻辑则由grammer搞定了。 </p> <p>原文链接：<a href="http://www.realdodo.com/blog/article.asp?id=216">http://www.realdodo.com/blog/article.asp?id=216</a></p></div></div></div></div></div></div></div></div><img src ="http://www.cppblog.com/woaidongmao/aggbug/50116.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/woaidongmao/" target="_blank">肥仔</a> 2008-05-17 00:16 <a href="http://www.cppblog.com/woaidongmao/archive/2008/05/17/50116.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>一些常用的正则表达式</title><link>http://www.cppblog.com/woaidongmao/archive/2008/05/10/49475.html</link><dc:creator>肥仔</dc:creator><author>肥仔</author><pubDate>Sat, 10 May 2008 14:25:00 GMT</pubDate><guid>http://www.cppblog.com/woaidongmao/archive/2008/05/10/49475.html</guid><wfw:comment>http://www.cppblog.com/woaidongmao/comments/49475.html</wfw:comment><comments>http://www.cppblog.com/woaidongmao/archive/2008/05/10/49475.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/woaidongmao/comments/commentRss/49475.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/woaidongmao/services/trackbacks/49475.html</trackback:ping><description><![CDATA[<div id="csdnblog_allwrap"> <form language="javascript" id="Form1" name="Form1" action="http://blog.csdn.net/544214.aspx" method="post"> <div id="csdnblog_midwrap"> <div id="csdnblog_content"> <div class="gutter"> <div class="default_contents"> <div class="user_article"> <div class="blogstory"> <p><span style="color: #000000">"</span><span style="color: #000000">^\d+$</span><span style="color: #000000">"</span><span style="color: #000000">　　</span><span style="color: #008000">//</span><span style="color: #008000">非负整数（正整数 + 0） </span><span style="color: #008000"><br><a href="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" target="_blank"></a></span><span style="color: #000000">"</span><span style="color: #000000">^[0-9]*[1-9][0-9]*$</span><span style="color: #000000">"</span><span style="color: #000000">　　</span><span style="color: #008000">//</span><span style="color: #008000">正整数 </span><span style="color: #008000"><br><a href="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" target="_blank"></a></span><span style="color: #000000">"</span><span style="color: #000000">^((-\d+)|(0+))$</span><span style="color: #000000">"</span><span style="color: #000000">　　</span><span style="color: #008000">//</span><span style="color: #008000">非正整数（负整数 + 0） </span><span style="color: #008000"><br><a href="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" target="_blank"></a></span><span style="color: #000000">"</span><span style="color: #000000">^-[0-9]*[1-9][0-9]*$</span><span style="color: #000000">"</span><span style="color: #000000">　　</span><span style="color: #008000">//</span><span style="color: #008000">负整数 </span><span style="color: #008000"><br><a href="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" target="_blank"></a></span><span style="color: #000000">"</span><span style="color: #000000">^-?\d+$</span><span style="color: #000000">"</span><span style="color: #000000">　　　　</span><span style="color: #008000">//</span><span style="color: #008000">整数 </span><span style="color: #008000"><br><a href="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" target="_blank"></a></span><span style="color: #000000">"</span><span style="color: #000000">^\d+(\.\d+)?$</span><span style="color: #000000">"</span><span style="color: #000000">　　</span><span style="color: #008000">//</span><span style="color: #008000">非负浮点数（正浮点数 + 0） </span><span style="color: #008000"><br><a href="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" target="_blank"></a></span><span style="color: #000000">"</span><span style="color: #000000">^(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*))$</span><span style="color: #000000">"</span><span style="color: #000000">　　</span><span style="color: #008000">//</span><span style="color: #008000">正浮点数 </span><span style="color: #008000"><br><a href="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" target="_blank"></a></span><span style="color: #000000">"</span><span style="color: #000000">^((-\d+(\.\d+)?)|(0+(\.0+)?))$</span><span style="color: #000000">"</span><span style="color: #000000">　　</span><span style="color: #008000">//</span><span style="color: #008000">非正浮点数（负浮点数 + 0） </span><span style="color: #008000"><br><a href="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" target="_blank"></a></span><span style="color: #000000">"</span><span style="color: #000000">^(-(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*)))$</span><span style="color: #000000">"</span><span style="color: #000000">　　</span><span style="color: #008000">//</span><span style="color: #008000">负浮点数 </span><span style="color: #008000"><br><a href="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" target="_blank"></a></span><span style="color: #000000">"</span><span style="color: #000000">^(-?\d+)(\.\d+)?$</span><span style="color: #000000">"</span><span style="color: #000000">　　</span><span style="color: #008000">//</span><span style="color: #008000">浮点数 </span><span style="color: #008000"><br><a href="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" target="_blank"></a></span><span style="color: #000000">"</span><span style="color: #000000">^[A-Za-z]+$</span><span style="color: #000000">"</span><span style="color: #000000">　　</span><span style="color: #008000">//</span><span style="color: #008000">由26个英文字母组成的字符串 </span><span style="color: #008000"><br><a href="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" target="_blank"></a></span><span style="color: #000000">"</span><span style="color: #000000">^[A-Z]+$</span><span style="color: #000000">"</span><span style="color: #000000">　　</span><span style="color: #008000">//</span><span style="color: #008000">由26个英文字母的大写组成的字符串 </span><span style="color: #008000"><br><a href="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" target="_blank"></a></span><span style="color: #000000">"</span><span style="color: #000000">^[a-z]+$</span><span style="color: #000000">"</span><span style="color: #000000">　　</span><span style="color: #008000">//</span><span style="color: #008000">由26个英文字母的小写组成的字符串 </span><span style="color: #008000"><br><a href="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" target="_blank"></a></span><span style="color: #000000">"</span><span style="color: #000000">^[A-Za-z0-9]+$</span><span style="color: #000000">"</span><span style="color: #000000">　　</span><span style="color: #008000">//</span><span style="color: #008000">由数字和26个英文字母组成的字符串 </span><span style="color: #008000"><br><a href="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" target="_blank"></a></span><span style="color: #000000">"</span><span style="color: #000000">^\w+$</span><span style="color: #000000">"</span><span style="color: #000000">　　</span><span style="color: #008000">//</span><span style="color: #008000">由数字、26个英文字母或者下划线组成的字符串 </span><span style="color: #008000"><br><a href="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" target="_blank"></a></span><span style="color: #000000">"</span><span style="color: #000000">^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+$</span><span style="color: #000000">"</span><span style="color: #000000">　　　　</span><span style="color: #008000">//</span><span style="color: #008000">email地址 </span><span style="color: #008000"><br><a href="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" target="_blank"></a></span><span style="color: #000000">"</span><span style="color: #000000">^[a-zA-z]+://(\w+(-\w+)*)(\.(\w+(-\w+)*))*(\?\S*)?$</span><span style="color: #000000">"</span><span style="color: #000000">　　</span><span style="color: #008000">//</span><span style="color: #008000">url</span><span style="color: #008000"><br><a href="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif" target="_blank"></a><a href="http://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif" target="_blank"></a></span><span style="color: #000000">/^</span><span style="color: #000000">(d</span><span id="Codehighlighter1_768_770_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><a href="http://www.cnblogs.com/Images/dot.gif" target="_blank"></a></span><span id="Codehighlighter1_768_770_Open_Text"><span style="color: #000000">{</span><span style="color: #000000">2</span><span style="color: #000000">}</span></span><span style="color: #000000">|</span><span style="color: #000000">d</span><span id="Codehighlighter1_774_776_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><a href="http://www.cnblogs.com/Images/dot.gif" target="_blank"></a></span><span id="Codehighlighter1_774_776_Open_Text"><span style="color: #000000">{</span><span style="color: #000000">4</span><span style="color: #000000">}</span></span><span style="color: #000000">)</span><span style="color: #000000">-</span><span style="color: #000000">((</span><span style="color: #000000">0</span><span style="color: #000000">([</span><span style="color: #000000">1</span><span style="color: #000000">-</span><span style="color: #000000">9</span><span style="color: #000000">]</span><span id="Codehighlighter1_788_790_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><a href="http://www.cnblogs.com/Images/dot.gif" target="_blank"></a></span><span id="Codehighlighter1_788_790_Open_Text"><span style="color: #000000">{</span><span style="color: #000000">1</span><span style="color: #000000">}</span></span><span style="color: #000000">))</span><span style="color: #000000">|</span><span style="color: #000000">(</span><span style="color: #000000">1</span><span style="color: #000000">[</span><span style="color: #000000">1</span><span style="color: #000000">|</span><span style="color: #000000">2</span><span style="color: #000000">]))</span><span style="color: #000000">-</span><span style="color: #000000">(([</span><span style="color: #000000">0</span><span style="color: #000000">-</span><span style="color: #000000">2</span><span style="color: #000000">]([</span><span style="color: #000000">1</span><span style="color: #000000">-</span><span style="color: #000000">9</span><span style="color: #000000">]</span><span id="Codehighlighter1_817_819_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><a href="http://www.cnblogs.com/Images/dot.gif" target="_blank"></a></span><span id="Codehighlighter1_817_819_Open_Text"><span style="color: #000000">{</span><span style="color: #000000">1</span><span style="color: #000000">}</span></span><span style="color: #000000">))</span><span style="color: #000000">|</span><span style="color: #000000">(</span><span style="color: #000000">3</span><span style="color: #000000">[</span><span style="color: #000000">0</span><span style="color: #000000">|</span><span style="color: #000000">1</span><span style="color: #000000">]))$</span><span style="color: #000000">/</span><span style="color: #000000">&nbsp;&nbsp; </span><span style="color: #008000">//</span><span style="color: #008000">&nbsp; 年-月-日</span><span style="color: #008000"><br><a href="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif" target="_blank"></a><a href="http://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif" target="_blank"></a></span><span style="color: #000000">/^</span><span style="color: #000000">((</span><span style="color: #000000">0</span><span style="color: #000000">([</span><span style="color: #000000">1</span><span style="color: #000000">-</span><span style="color: #000000">9</span><span style="color: #000000">]</span><span id="Codehighlighter1_858_860_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><a href="http://www.cnblogs.com/Images/dot.gif" target="_blank"></a></span><span id="Codehighlighter1_858_860_Open_Text"><span style="color: #000000">{</span><span style="color: #000000">1</span><span style="color: #000000">}</span></span><span style="color: #000000">))</span><span style="color: #000000">|</span><span style="color: #000000">(</span><span style="color: #000000">1</span><span style="color: #000000">[</span><span style="color: #000000">1</span><span style="color: #000000">|</span><span style="color: #000000">2</span><span style="color: #000000">]))</span><span style="color: #000000">/</span><span style="color: #000000">(([</span><span style="color: #000000">0</span><span style="color: #000000">-</span><span style="color: #000000">2</span><span style="color: #000000">]([</span><span style="color: #000000">1</span><span style="color: #000000">-</span><span style="color: #000000">9</span><span style="color: #000000">]</span><span id="Codehighlighter1_888_890_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><a href="http://www.cnblogs.com/Images/dot.gif" target="_blank"></a></span><span id="Codehighlighter1_888_890_Open_Text"><span style="color: #000000">{</span><span style="color: #000000">1</span><span style="color: #000000">}</span></span><span style="color: #000000">))</span><span style="color: #000000">|</span><span style="color: #000000">(</span><span style="color: #000000">3</span><span style="color: #000000">[</span><span style="color: #000000">0</span><span style="color: #000000">|</span><span style="color: #000000">1</span><span style="color: #000000">]))</span><span style="color: #000000">/</span><span style="color: #000000">(d</span><span id="Codehighlighter1_908_910_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><a href="http://www.cnblogs.com/Images/dot.gif" target="_blank"></a></span><span id="Codehighlighter1_908_910_Open_Text"><span style="color: #000000">{</span><span style="color: #000000">2</span><span style="color: #000000">}</span></span><span style="color: #000000">|</span><span style="color: #000000">d</span><span id="Codehighlighter1_914_916_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><a href="http://www.cnblogs.com/Images/dot.gif" target="_blank"></a></span><span id="Codehighlighter1_914_916_Open_Text"><span style="color: #000000">{</span><span style="color: #000000">4</span><span style="color: #000000">}</span></span><span style="color: #000000">)$</span><span style="color: #000000">/</span><span style="color: #000000">&nbsp;&nbsp; </span><span style="color: #008000">//</span><span style="color: #008000"> 月/日/年</span><span style="color: #008000"><br><a href="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" target="_blank"></a></span><span style="color: #000000">"</span><span style="color: #000000">^([w-.]+)@(([[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.)|(([w-]+.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(]?)$</span><span style="color: #000000">"</span><span style="color: #000000">&nbsp;&nbsp; </span><span style="color: #008000">//</span><span style="color: #008000">Emil</span><span style="color: #008000"><br><a href="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" target="_blank"></a></span><span style="color: #000000">"</span><span style="color: #000000">(d+-)?(d{4}-?d{7}|d{3}-?d{8}|^d{7,8})(-d+)?</span><span style="color: #000000">"</span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: #008000">//</span><span style="color: #008000">电话号码</span><span style="color: #008000"><br><a href="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" target="_blank"></a></span><span style="color: #000000">"</span><span style="color: #000000">^(d{1,2}|1dd|2[0-4]d|25[0-5]).(d{1,2}|1dd|2[0-4]d|25[0-5]).(d{1,2}|1dd|2[0-4]d|25[0-5]).(d{1,2}|1dd|2[0-4]d|25[0-5])$</span><span style="color: #000000">"</span><span style="color: #000000">&nbsp;&nbsp; </span><span style="color: #008000">//</span><span style="color: #008000">IP地址</span><br></p> <p></p> <p>匹配中文字符的正则表达式： [\u4e00-\u9fa5]<br>匹配双字节字符(包括汉字在内)：[^\x00-\xff]<br>匹配空行的正则表达式：\n[\s| ]*\r<br>匹配HTML标记的正则表达式：/&lt;(.*)&gt;.*&lt;\/\1&gt;|&lt;(.*) \/&gt;/<br>匹配首尾空格的正则表达式：(^\s*)|(\s*$)<br>匹配Email地址的正则表达式：\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*<br>匹配网址URL的正则表达式：^[a-zA-z]+://(\\w+(-\\w+)*)(\\.(\\w+(-\\w+)*))*(\\?\\S*)?$<br>匹配帐号是否合法(字母开头，允许5-16字节，允许字母数字下划线)：^[a-zA-Z][a-zA-Z0-9_]{4,15}$<br>匹配国内电话号码：(\d{3}-|\d{4}-)?(\d{8}|\d{7})?<br>匹配腾讯QQ号：^[1-9]*[1-9][0-9]*$<br></p> <p><u>下表是元字符及其在正则表达式上下文中的行为的一个完整列表： <br></u><br><strong>\</strong> 将下一个字符标记为一个特殊字符、或一个原义字符、或一个后向引用、或一个八进制转义符。<br><br><strong>^</strong> 匹配输入字符串的开始位置。如果设置了 RegExp 对象的Multiline 属性，^ 也匹配 ’\n’ 或 ’\r’ 之后的位置。 <br><br><strong>$</strong> 匹配输入字符串的结束位置。如果设置了 RegExp 对象的Multiline 属性，$ 也匹配 ’\n’ 或 ’\r’ 之前的位置。 <br><br><strong>*</strong> 匹配前面的子表达式零次或多次。 <br><br><strong>+</strong> 匹配前面的子表达式一次或多次。+ 等价于 {1,}。 <br><br><strong>?</strong> 匹配前面的子表达式零次或一次。? 等价于 {0,1}。 <br><br><strong>{n}</strong> n 是一个非负整数，匹配确定的n 次。<br><br><strong>{n,}</strong> n 是一个非负整数，至少匹配n 次。 <br><br><strong>{n,m}</strong> m 和 n 均为非负整数，其中n &lt;= m。最少匹配 n 次且最多匹配 m 次。在逗号和两个数之间不能有空格。<br><br><strong>?</strong> 当该字符紧跟在任何一个其他限制符 (*, +, ?, {n}, {n,}, {n,m}) 后面时，匹配模式是非贪婪的。非贪婪模式尽可能少的匹配所搜索的字符串，而默认的贪婪模式则尽可能多的匹配所搜索的字符串。 <br><br><strong>.</strong> 匹配除 "\n" 之外的任何单个字符。要匹配包括 ’\n’ 在内的任何字符，请使用象 ’[.\n]’ 的模式。 <br><strong>(pattern)</strong> 匹配pattern 并获取这一匹配。 <br><br><strong>(?:pattern)</strong> 匹配pattern 但不获取匹配结果，也就是说这是一个非获取匹配，不进行存储供以后使用。 <br><br><strong>(?=pattern)</strong> 正向预查，在任何匹配 pattern 的字符串开始处匹配查找字符串。这是一个非获取匹配，也就是说，该匹配不需要获取供以后使用。 <br><br><strong>(?!pattern)</strong> 负向预查，与<strong>(?=pattern)</strong>作用相反 <br><br><strong>x|y</strong> 匹配 x 或 y。 <br><br><strong>[xyz]</strong> 字符集合。 <br><br><strong>[^xyz]</strong> 负值字符集合。 <br><br><strong>[a-z]</strong> 字符范围，匹配指定范围内的任意字符。 <br><br><strong>[^a-z]</strong> 负值字符范围，匹配任何不在指定范围内的任意字符。 <br><br><strong>\b</strong> 匹配一个单词边界，也就是指单词和空格间的位置。<br><br><strong>\B</strong> 匹配非单词边界。 <br><br><strong>\cx</strong> 匹配由x指明的控制字符。 <br><br><strong>\d</strong> 匹配一个数字字符。等价于 [0-9]。 <br><br><strong>\D</strong> 匹配一个非数字字符。等价于 [^0-9]。 <br><br><strong>\f</strong> 匹配一个换页符。等价于 \x0c 和 \cL。 <br><br><strong>\n</strong> 匹配一个换行符。等价于 \x0a 和 \cJ。 <br><br><strong>\r</strong> 匹配一个回车符。等价于 \x0d 和 \cM。 <br><br><strong>\s</strong> 匹配任何空白字符，包括空格、制表符、换页符等等。等价于[ \f\n\r\t\v]。 <br><br><strong>\S</strong> 匹配任何非空白字符。等价于 [^ \f\n\r\t\v]。 <br><br><strong>\t</strong> 匹配一个制表符。等价于 \x09 和 \cI。 <br><br><strong>\v</strong> 匹配一个垂直制表符。等价于 \x0b 和 \cK。 <br><br><strong>\w</strong> 匹配包括下划线的任何单词字符。等价于’[A-Za-z0-9_]’。 <br><br><strong>\W</strong> 匹配任何非单词字符。等价于 ’[^A-Za-z0-9_]’。 <br><br><strong>\xn</strong> 匹配 n，其中 n 为十六进制转义值。十六进制转义值必须为确定的两个数字长。<br><br><strong>\num</strong> 匹配 num，其中num是一个正整数。对所获取的匹配的引用。 <br><br><strong>\n</strong> 标识一个八进制转义值或一个后向引用。如果 \n 之前至少 n 个获取的子表达式，则 n 为后向引用。否则，如果 n 为八进制数字 (0-7)，则 n 为一个八进制转义值。 <br><br><strong>\nm</strong> 标识一个八进制转义值或一个后向引用。如果 \nm 之前至少有is preceded by at least nm 个获取得子表达式，则 nm 为后向引用。如果 \nm 之前至少有 n 个获取，则 n 为一个后跟文字 m 的后向引用。如果前面的条件都不满足，若 n 和 m 均为八进制数字 (0-7)，则 \nm 将匹配八进制转义值 nm。 <br><br><strong>\nml</strong> 如果 n 为八进制数字 (0-3)，且 m 和 l 均为八进制数字 (0-7)，则匹配八进制转义值 nml。 <br><br><strong>\un</strong> 匹配 n，其中 n 是一个用四个十六进制数字表示的Unicode字符。 <br></p> <p>匹配中文字符的正则表达式： [u4e00-u9fa5]</p> <p>匹配双字节字符(包括汉字在内)：[^x00-xff]</p> <p>应用：计算字符串的长度（一个双字节字符长度计2，ASCII字符计1）</p> <p>String.prototype.len=function(){return this.replace([^x00-xff]/g,"aa").length;}</p> <p>匹配空行的正则表达式：n[s| ]*r</p> <p>匹配HTML标记的正则表达式：/&lt;(.*)&gt;.*&lt;/1&gt;|&lt;(.*) /&gt;/ </p> <p>匹配首尾空格的正则表达式：(^s*)|(s*$)</p> <p>应用：javascript中没有像vbscript那样的trim函数，我们就可以利用这个表达式来实现，如下：</p> <p>String.prototype.trim = function()<br>{<br>return this.replace(/(^s*)|(s*$)/g, "");<br>}</p> <p>利用正则表达式分解和转换IP地址：</p> <p>下面是利用正则表达式匹配IP地址，并将IP地址转换成对应数值的Javascript程序：</p> <p>function IP2V(ip)<br>{<br>re=/(d+).(d+).(d+).(d+)/g //匹配IP地址的正则表达式<br>if(re.test(ip))<br>{<br>return RegExp.$1*Math.pow(255,3))+RegExp.$2*Math.pow(255,2))+RegExp.$3*255+RegExp.$4*1<br>}<br>else<br>{<br>throw new Error("Not a valid IP address!")<br>}<br>}</p> <p>不过上面的程序如果不用正则表达式，而直接用split函数来分解可能更简单，程序如下：</p> <p>var ip="10.100.20.168"<br>ip=ip.split(".")<br>alert("IP值是："+(ip[0]*255*255*255+ip[1]*255*255+ip[2]*255+ip[3]*1))</p> <p>匹配Email地址的正则表达式：w+([-+.]w+)*@w+([-.]w+)*.w+([-.]w+)*</p> <p>匹配网址URL的正则表达式：http://([w-]+.)+[w-]+(/[w- ./?%&amp;=]*)?</p> <p>利用正则表达式去除字串中重复的字符的算法程序：</p> <p>var s="abacabefgeeii"<br>var s1=s.replace(/(.).*1/g,"$1")<br>var re=new RegExp("["+s1+"]","g")<br>var s2=s.replace(re,"") <br>alert(s1+s2) //结果为：abcefgi</p> <p>我原来在CSDN上发贴寻求一个表达式来实现去除重复字符的方法，最终没有找到，这是我能想到的最简单的实现方法。思路是使用后向引用取出包括重复的字符，再以重复的字符建立第二个表达式，取到不重复的字符，两者串连。这个方法对于字符顺序有要求的字符串可能不适用。</p> <p>得用正则表达式从URL地址中提取文件名的javascript程序，如下结果为page1</p> <p>s="http://www.9499.net/page1.htm"<br>s=s.replace(/(.*/){0,}([^.]+).*/ig,"$2")<br>alert(s)</p> <p>利用正则表达式限制网页表单里的文本框输入内容：</p> <p>用正则表达式限制只能输入中文：onkeyup="value=value.replace(/[^u4E00-u9FA5]/g,'')" onbeforepaste="clipboardData.setData('text',clipboardData.getData('text').replace(/[^u4E00-u9FA5]/g,''))"</p> <p>用正则表达式限制只能输入全角字符： onkeyup="value=value.replace(/[^uFF00-uFFFF]/g,'')" onbeforepaste="clipboardData.setData('text',clipboardData.getData('text').replace(/[^uFF00-uFFFF]/g,''))"</p> <p>用正则表达式限制只能输入数字：onkeyup="value=value.replace(/[^d]/g,'') "onbeforepaste="clipboardData.setData('text',clipboardData.getData('text').replace(/[^d]/g,''))"</p> <p>用正则表达式限制只能输入数字和英文：onkeyup="value=value.replace(/[W]/g,'') "onbeforepaste="clipboardData.setData('text',clipboardData.getData('text').replace(/[^d]/g,''))"</p></div></div></div></div></div></div></form></div><img src ="http://www.cppblog.com/woaidongmao/aggbug/49475.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/woaidongmao/" target="_blank">肥仔</a> 2008-05-10 22:25 <a href="http://www.cppblog.com/woaidongmao/archive/2008/05/10/49475.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>VC6中使用STLPort4.6.2</title><link>http://www.cppblog.com/woaidongmao/archive/2008/05/07/49105.html</link><dc:creator>肥仔</dc:creator><author>肥仔</author><pubDate>Wed, 07 May 2008 02:53:00 GMT</pubDate><guid>http://www.cppblog.com/woaidongmao/archive/2008/05/07/49105.html</guid><wfw:comment>http://www.cppblog.com/woaidongmao/comments/49105.html</wfw:comment><comments>http://www.cppblog.com/woaidongmao/archive/2008/05/07/49105.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/woaidongmao/comments/commentRss/49105.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/woaidongmao/services/trackbacks/49105.html</trackback:ping><description><![CDATA[<p>编译就不说了, 网上这方面的文章很多 <p>********************************************<br>如果和PlatformSDK 一起使用的话<br>要记的在STLport目录中 \stlport\stl_user_config.h 文件中<br>把这一句打开 <p>&nbsp;&nbsp;&nbsp;&nbsp; # define _STLP_NEW_PLATFORM_SDK 1  <p>否则在编译时会有如下错误<br>second C linkage of overloaded function 'InterlockedIncrement' not allowed <p>******************************************** <p>如果想静态链接 STLPort 请在VC6的 C/C++ \ General \ Preprocessor definitions<br>中添加宏 _STLP_USE_STATIC_LIB <p>******************************************** <p>对於使用IOSTREAM的, 如果有问题<br>在STLport目录中 \stlport\stl_user_config.h 文件中<br>把这一句打开吧 <p>&nbsp;&nbsp;&nbsp; # define _STLP_NO_IOSTREAMS 1 <p>******************************************** <p>- When you erase an element from a hash_map only iterators to the erased element are invalidated <br>&nbsp; so you can write something like: <p>while (it != myHashMap.end()) {<br>if (condition)<br> myHashMap.erase(it++); //这里为何这样不出错 而把it++放外面就不行呢<br>&nbsp;&nbsp;&nbsp; //在外面是对删除后的无效指针加, 而里面是对有效指针加<br>else<br> ++it;<br>} <p>&nbsp; To finish STLport has a special debug mode to check such bad construction. Check the <br>&nbsp; stl_user_config.h file in the stlport folder for that, the macro is _STLP_DEBUG. <img src ="http://www.cppblog.com/woaidongmao/aggbug/49105.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/woaidongmao/" target="_blank">肥仔</a> 2008-05-07 10:53 <a href="http://www.cppblog.com/woaidongmao/archive/2008/05/07/49105.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Boost.Python</title><link>http://www.cppblog.com/woaidongmao/archive/2008/04/25/48144.html</link><dc:creator>肥仔</dc:creator><author>肥仔</author><pubDate>Fri, 25 Apr 2008 09:54:00 GMT</pubDate><guid>http://www.cppblog.com/woaidongmao/archive/2008/04/25/48144.html</guid><wfw:comment>http://www.cppblog.com/woaidongmao/comments/48144.html</wfw:comment><comments>http://www.cppblog.com/woaidongmao/archive/2008/04/25/48144.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/woaidongmao/comments/commentRss/48144.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/woaidongmao/services/trackbacks/48144.html</trackback:ping><description><![CDATA[<p><a href="http://www.boost.org/libs/python/doc/index.html">Boost.Python</a><a name="idx001"></a> 是 <a href="http://www.boost.org/">Boost</a><a name="idx002"></a> 中的一个组件， 使用它能够大大简化用 C++ 为 Python 写扩展库的步骤，提高开发效率， 虽然目前它对 Python 嵌入 C++ 的支持还不是很多， 但也能提供很大方便。另外， <a href="http://bug.codecarver.org/">华宇煜</a><a name="idx003"></a>也编写了一份关于 <a href="http://bug.codecarver.org/python/boost.html">Boost.Python 简明教程</a><a name="idx004"></a>。 <h3><a name="hd001"></a>1 Boost 安装简介</h3> <p>在正式开始使用 Boost.Python 之前， 我们必须先编译 Boost。 首先到 <a href="http://www.boost.org/">Boost 的官方站点</a><a name="idx005"></a> 下载 Boost 的源码包， 把它们解压到你喜欢的目录，为编译做好准备。 另外， 在正式安装 Boost.Python 之前， 我们必须先正确安装 Python。 <h4><a name="hd001001"></a>1.1 Linux 下的编译</h4> <p>首先切换到 Boost 源码所在的路径， 执行 <code>./configure</code> 脚本，为配置脚本提供 Python 运行环境相应的参数：<pre>./configure --with-python=/usr/bin/python \
            --with-python-version=2.4 \
            --with-python-root=/usr
</pre>
<p>然后， 和绝大部分 Linux 程序一行， 执行 <code>make</code> 就可以开始编译了。编译完毕后， 切换到 root 权限后再执行 <code>make install</code>，把 Boost 相应的头文件和库文件复制到相应的地方， 就可以使用了。
<h4><a name="hd001002"></a>1.2 使用 MinGW + MSys 在 Windows 下的编译</h4>
<p>首先需要编译的是 Boost 的编译工具 bjam， 直接到 bjam 所在目录下， 即 Boost 源码包所在目录下的 <code>\tools\build\jam_src</code>， 执行 <code>build.bat mingw</code>，稍等片刻， bjam.exe 就编译好了。 把编译好的 bjam.exe 复制到你的 <code>%PATH%</code> 路径能够直接找到的地方， 为后续的编译工作做好准备。
<p>接下来， 切换到 Boost 源码所在路径， 执行 bjam 进行编译。 我们需要提供关于 Python 的一些参数， 变量 PYTHON_ROOT 指向 Python 运行环境所在的目录，变量 PYTHON_VERSION 的值为 Python 的版本号， 如果你的 Python 安装路径与滇狐不同，请将相应的变量修改为你机器上相应的路径， 编译命令行如下：<pre>bjam.exe "-sTOOLS=mingw" "-sPYTHON_ROOT=E:\Python" "-sPYTHON_VERSION=2.4"
</pre>
<p>编译完毕后， 你将会在你的 <code>C:\Boost</code> 下找到编译得到的 Boost 相应头文件与库文件， 你可以根据你的需要将它移动到别的地方备用。
<h3><a name="hd002"></a>2 使用 Boost.Python 嵌入 Python 模块到 C++</h3>
<p>Boost.Python 目前并没有提供完整的将 Python 模块嵌入到 C++ 的包装库，因此许多工作我们还必须通过 Python C API 来进行。 但是， 利用 Boost.Python 中提供的一些模块， 能够给我们的工作带来极大便利。
<h4><a name="hd002001"></a>2.1 修改模块加载路径，装入 Python 模块</h4>
<p>与任何一个其它 Python 嵌入 C/C++ 的程序一样， 我们需要在第一条 <code>#include</code> 语句处含入 <code>Python.h</code>， 并在程序开始时调用 <code>Py_Initialize()</code>，在程序结束时调用 <code>Py_Finalize()</code>。
<p>接下来， 我们便可以开始准备装入 Python 模块了。 为了让 Python 解释器能够正确地找到 Python 模块所在的位置， 我们需要将 Python 模块所在的路径添加到模块搜索路径中，添加搜索路径的 Python 语句如下：<pre>import sys
<b>if</b> <b>not</b> '/module/path' <b>in</b> sys.path:
    sys.path.append('/module/path')
</pre>
<p>我们使用 Python C API 执行类似的语句， 就能将模块的搜索路径添加到 Python 解释器中。 添加了搜索路径后， 就可以通过 <code>PyImport_ImportModule</code> 函数加载 Python 模块了。 <code>PyImport_ImportModule</code> 返回值是 <code>PyObject *</code>， 为了避免手工处理繁琐的引用计数等问题，我们求助于 Boost.Python 提供的 <code>handle</code> 模块， 将 <code>PyObject *</code> 封装起来， 以方便使用， 代码如下：<pre>#include &lt;boost/python.hpp&gt;

...

    boost::python::handle&lt;&gt;* _module; // Module handle.
    std::string path; // Path of the Python module.
    std::string module; // Module name.

...

    <b>try</b>
    {
        PyRun_SimpleString("import sys");
        PyRun_SimpleString((std::string("if not '") + path
            + "' in sys.path: sys.path.append('" + path + "')").c_str());
        _module = <b>new</b> boost::python::handle&lt;&gt;(
            PyImport_ImportModule((<b>char</b> *) module));
        ...
    }
    <b>catch</b> (...)
    {
        PyErr_Print();
        PyErr_Clear();
        <b>delete</b> _module;
        _module = NULL;
        <b>return</b> false;
    }

...
</pre>
<p>需要注意的是， 通过 Python C API 加载的 Python 解释器并没有把当前路径列入默认的搜索路径中。因此， 即使你的 Python 模块就存放在当前路径， 你也必须使用上面的代码将当前路径添加到搜索路径中之后，才能通过 <code>PyImport_ImportModule</code> 加载到模块。
<p>当 Python 模块使用完毕或程序结束时， 请使用 <code>delete</code> 将 <code>_module</code> 指针释放， <code>handle</code> 被释放的时候会自动释放相应的 Python 模块并回收相应资源。
<h4><a name="hd002002"></a>2.2 调用 Python 函数</h4>
<p>导入了 Python 模块之后， 调用 Python 函数就非常容易了。 Boost.Python 里封装了一个非常好用的模板函数 <code>boost::python::call_method</code>，它可以替你处理调用函数时需要处理的种种细节， 将你从 Python C API 中繁琐的“将参数打包为 <code>PyObject *</code>”、 “构造 Tuple”、 “传递 Tuple”、 “解包返回值”等工作中彻底解放出来， 你只需要这样：<pre>    boost::python::call_method&lt;返回值类型&gt;(模块指针, "Python 函数名",
        参数 1, 参数 2, ...);
</pre>
<p>模块指针可以通过我们前面得到的 <code>_module</code> 的 <code>get</code> 方法获得， 例如：<pre>...
    <b>bool</b> result;
    std::string config_file;

    ...

    <b>try</b>
    {
        <b>return</b> boost::python::call_method&lt;<b>bool</b>&gt;(_module-&gt;get(), "initialize",
            config_file);
    }
    <b>catch</b> (...)
    {
        PyErr_Print();
        PyErr_Clear();
        ...
    }

...
</pre>
<h4><a name="hd002003"></a>2.3 使用 Python 类对象</h4>
<p>使用 Python C API 调用 Python 函数和调用 Python 类对象是没有太大区别的，我们只需要调用类的构造方法， 得到一个类对象， 然后把该类的指针看做模块指针，按照前面调用普通函数的方法调用类成员方法就可以了。 例如， 下列代码从 <code>_module</code> 中创建了一个 <code>YukiSession</code> 对象， 然后调用了其中的 <code>on_welcome</code> 方法。 除了展示调用类成员方法外， 这段代码还展示了构造 Python list 对象、 从 Python list 对象中获取元素的方式。<pre>    ...

    boost::python::handle&lt;&gt; _yukisession;

    ...

    // Retrieve the module handle and namespace handle.
    boost::python::object main_module(*_module);
    boost::python::object main_namespace = main_module.attr("__dict__");

    // Call the method and get the object handle.
    _yukisession = boost::python::handle&lt;&gt;((PyRun_String(
        "YukiSession()", Py_eval_input,
        main_namespace.ptr(), main_namespace.ptr())));
    ...

    // Compose a list.
    boost::python::list param;
    param.append(boost::python::str(_addr.get_host_addr()));
    param.append(boost::python::str());

    // Call the method and retrieve the result.
    // Method is equivalent to:
    // "bool __thiscall YukiSession::on_welcome(list param);"
    result = boost::python::call_method&lt;<b>bool</b>&gt;
        (_yukisession.get(), "on_welcome", param);
    // Extract an item from a list.
    str = boost::python::call_method&lt;std::string&gt;
        (param.ptr(), "__getitem__", 1);

    ...
</pre>
<h3><a name="hd003"></a>3 在嵌入的 Python 模块中调用 C++ 程序</h3>
<p>通过动态链接库的方式使用 Boost.Python 导出 C++ 模块到 Python 程序与在 C++ 可执行程序中导出模块给嵌入的 Python 解释器， 编写程序的方式几乎是完全相同的。因此这里只简单介绍导出普通函数的方法， 想详细了解更多高级功能， 如导出 C++ 类、 导出可被 Python 重载的类等， 可以参看华宇煜的 <a href="http://bug.codecarver.org/python/boost.html">Boost.Python 简明教程</a><a name="idx006"></a>或官方 <a href="http://www.boost.org/libs/python/doc/index.html">Boost.Python</a><a name="idx007"></a> 文档。
<h4><a name="hd003001"></a>3.1 导出 C++ 函数</h4>
<p>首先使用 <code>BOOST_PYTHON_MODULE</code> 宏定义需要导出给 Python 的模块，然后用 <code>boost::python::def</code> 语句定义导出的函数、 参数列表以及 Doc String， 例如在下面的例子中， 我们导出了一个 C++ 函数 <code>yukigettext</code>，并重命名为 <code>gettext</code>：<pre><b>const</b> <b>char</b> *yukigettext(<b>const</b> <b>char</b> *id);

BOOST_PYTHON_MODULE(yuki)
{
    boost::python::def("gettext", yukigettext,
        boost::python::args("id"), "Translate message.");
}
</pre>
<h4><a name="hd003002"></a>3.2 为 Python 初始化 C++ 模块</h4>
<p>使用 <code>BOOST_PYTHON_MODULE(name)</code> 定义了 Python 模块后，该宏会自动生成一个函数 <code>initname</code>， 我们需要在 <code>Py_Initialize()</code> 之后调用这个自动生成的函数， 初始化导出到 Python 的模块。 例如我们刚才导出模块用的宏 <code>BOOST_PYTHON_MODULE(yuki)</code>， 因此初始化的时候就应该调用 <code>inityuki()</code>：<pre>...
    Py_Initialize();
    inityuki();
...
</pre>
<h4><a name="hd003003"></a>3.3 在 Python 模块中调用 C++ 模块</h4>
<p>此时我们在 Python 模块中只需要像普通的 Python 模块那样， 将导入的 C++ 模块用 <code>import</code> 语句加载进来， 就可以调用了：<pre>import yuki

...

<b>print</b> yuki.gettext("This is a test!")
</pre><img src ="http://www.cppblog.com/woaidongmao/aggbug/48144.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/woaidongmao/" target="_blank">肥仔</a> 2008-04-25 17:54 <a href="http://www.cppblog.com/woaidongmao/archive/2008/04/25/48144.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>对字符串类型和数值类型间进行转换问题的处理之Boost组件lexical_cast</title><link>http://www.cppblog.com/woaidongmao/archive/2008/04/25/48140.html</link><dc:creator>肥仔</dc:creator><author>肥仔</author><pubDate>Fri, 25 Apr 2008 09:08:00 GMT</pubDate><guid>http://www.cppblog.com/woaidongmao/archive/2008/04/25/48140.html</guid><wfw:comment>http://www.cppblog.com/woaidongmao/comments/48140.html</wfw:comment><comments>http://www.cppblog.com/woaidongmao/archive/2008/04/25/48140.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/woaidongmao/comments/commentRss/48140.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/woaidongmao/services/trackbacks/48140.html</trackback:ping><description><![CDATA[<p>在CSDN论坛上经常看到询问如何在字符串类型和数值类型间进行转换的问题，也看到了许多不同的答案。下面先讨论一下从字符串类型到数值类型的转换。  <ol> <li>如何将字符串"123"转换为int类型整数123？答案是，用标准C的库函数atoi；  <li>如果要转换为long类型呢？标准C的库函数atol；  <li>如何将"123.12"转换为double类型呢？标准C的库函数atod；  <li>如果要转换为long double类型呢？标准C的库函数atold；  <li>…… </li></ol> <p>后来有朋友开始使用标准库中的string类，问这个如何转换为数值？有朋友答曰，请先转换为const char*。我很佩服作答者有数学家的思维：把陌生的问题转化成熟悉的问题。（曾经有一则笑话，好事者问数学家：知道如何烧水吗？答：知道。把水壶加满水，点火烧。又问：如果水壶里已经有水了呢？答：先倒掉，就转化为我熟悉的问题了……）  <p>不，不，这样是C的做法，不是C++。那么，C++该怎么做呢？使用Boost Conversion Library所提供的函数lexical_cast（需要引入头文件boost/lexical_cast.hpp）无疑是最简单方便的。如： <pre><pre>#include &lt;boost/lexical_cast.hpp&gt;
#include &lt;iostream&gt;
int main()
{
        using boost::lexical_cast;
        int a = lexical_cast&lt;int&gt;("123");
        double b = lexical_cast&lt;double&gt;("123.12");
        std::cout&lt;&lt;a&lt;&lt;std::endl
        std::cout&lt;&lt;b&lt;&lt;std::endl;
        return 0;
}</pre></pre>
<p>一个函数就简洁地解决了所有的问题。 
<h6><a name="3.2 数值&rarr;字符串"></a>3.2 数值→字符串 </h6>
<p>那么从数值类型到字符串类型呢？ 
<p>用itoa？不对吧，标准C/C++里根本没有这个函数。即使在Windows平台下某些编译器提供了该函数<a href="http://www.stlchina.org/twiki/bin/view.pl/Main/BoostEnterBoost#MyNote3">3</a>，没有任何移植性不说，还只能解决int类型（也许其他函数还可以解决long、unsigned long等类型），浮点类型又怎么办？当然，办法还是有，那就是：sprintf。 <pre><pre>char s[100];
sprintf(s, "%f", 123.123456);</pre></pre>
<p>不知道诸位对C里的scanf/printf系列印象如何，总之阿炯我肯定记不住那些稀奇古怪的参数，而且如果写错了参数，就会得到莫名其妙的输出结果，调试起来可就要命了（我更讨厌的是字符数组，空间开100呢，又怕太小装不下；开100000呢，总觉得太浪费，心里憋气，好在C++标准为我们提供了string这样的字符串类）。这时候，lexical_cast就出来帮忙啦。 <pre><pre>#include &lt;boost/lexical_cast.hpp&gt;
#include &lt;string&gt;
#include &lt;iostream&gt;
int main()
{
        using std::string;
        const double d = 123.12;
        string s = boost::lexical_cast&lt;string&gt;(d);
        std::cout&lt;&lt;s&lt;&lt;std::endl;
        return 0;
}</pre></pre>
<p>跟前面一样简单。 
<h6><a name="3.3 异常"></a>3.3 异常 </h6>
<p>如果转换失败，则会有异常bad_lexical_cast抛出。该异常类是标准异常类bad_cast的子类。 <pre><pre>#include &lt;boost/lexical_cast.hpp&gt;
#include &lt;iostream&gt;
int main()
{
        using std::cout;
        using std::endl;
        int i;
        try{
                i = boost::lexical_cast&lt;int&gt;("abcd");
        }
        catch(boost::bad_lexical_cast&amp; e)
        {
                cout&lt;&lt;e.what()&lt;&lt;endl;
                return 1;
        }
        cout&lt;&lt;i&lt;&lt;endl;
        return 0;
}</pre></pre>
<p>显然“abcd”并不能转换为一个int类型的数值，于是抛出异常，捕捉后输出“bad lexical cast: source type value could not be interpreted as target”这样的信息。 
<h6><a name="3.4 注意事项"></a>3.4 注意事项 </h6>
<p>lexical_cast依赖于字符流std::stringstream（会自动引入头文件<a href="http://www.stlchina.org/twiki/bin/view.pl/Main/BoostEnterBoost#MyNote4">4</a>），其原理相当简单：把源类型读入到字符流中，再写到目标类型中，就大功告成。例如 <pre><pre>int d = boost::lexical_cast&lt;int&gt;("123");</pre></pre>
<p>就相当于 <pre><pre>int d;
std::stringstream s;
s&lt;&lt;"123";
s&gt;&gt;d;</pre></pre>
<p>既然是使用了字符流，当然就有些随之而来的问题，需要特别指出<a href="http://www.stlchina.org/twiki/bin/view.pl/Main/BoostEnterBoost#MyNote5">5</a>。 
<ul>
<li>由于Visual C++ 6的本地化（locale）部分实现有问题，因此如果使用了非默认的locale，可能会莫名其妙地抛出异常。当然，一般情况下我们并不需要去改变默认的locale，所以问题不是很大。 
<li>输入数据必须“完整”地转换，否则抛出bad_lexical_cast异常。例如 </li></ul><pre><pre>int i = boost::lexical_cast&lt;int&gt;("123.123"); // this will throw </pre></pre>
<p>便会抛出异常。因为“123.123”只能“部分”地转换为123，不能“完整”地转换为123.123。 
<ul>
<li>浮点数的精度问题。 </li></ul><pre><pre>std::string s = boost::lexical_cast&lt;std::string&gt;(123.1234567);</pre></pre>
<p>以上语句预想的结果是得到“123.1234567”，但是实际上我们只会得到“123.123”，因为默认情况下std::stringstream的精度是6（这是C语言程序库中的“前辈”printf留下的传统）。这可以说是boost::lexical_cast的一个bug。怎么办呢？权宜之计，可以这么做：打开头文件&lt;boost/lexical_cast.hpp&gt;，注意对照修改<a href="http://www.stlchina.org/twiki/bin/view.pl/Main/BoostEnterBoost#MyNote6">6</a>： <pre><pre>#include &lt;boost/limits.hpp&gt;
//...
template&lt;typename Target, typename Source&gt;
Target lexical_cast(Source arg) {
        //...
        Target result; 
        interpreter.precision(std::numeric_limits&lt;Source&gt;::digits10);
        if( !(interpreter &lt;&lt; arg) ||
        !(interpreter &gt;&gt; result) ||
        !(interpreter &gt;&gt; std::ws).eof())
        //...
}</pre></pre>
<p>即可得到正确结果。当然，理论上效率会有一点点损失，不过几乎可以忽略不计。 
<h5><a name="4 小结"></a>4 小结 </h5>
<hr>
我们已经体验了boost::lexcial_cast。当然，lexical_cast不仅仅局限于字符串类型与数值类型之间的转换：可在任意可输出到stringstream的类型和任意可从stringstream输入的类型间转换。这次的了解尽管很粗略，不过毕竟我们已经“走进Boost”，而不仅仅是“走近”。以后，我们可以自行领略Boost的动人之处啦。
<img src ="http://www.cppblog.com/woaidongmao/aggbug/48140.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/woaidongmao/" target="_blank">肥仔</a> 2008-04-25 17:08 <a href="http://www.cppblog.com/woaidongmao/archive/2008/04/25/48140.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>STLPort 5.1.5 编译</title><link>http://www.cppblog.com/woaidongmao/archive/2008/04/25/48093.html</link><dc:creator>肥仔</dc:creator><author>肥仔</author><pubDate>Thu, 24 Apr 2008 16:56:00 GMT</pubDate><guid>http://www.cppblog.com/woaidongmao/archive/2008/04/25/48093.html</guid><wfw:comment>http://www.cppblog.com/woaidongmao/comments/48093.html</wfw:comment><comments>http://www.cppblog.com/woaidongmao/archive/2008/04/25/48093.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/woaidongmao/comments/commentRss/48093.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/woaidongmao/services/trackbacks/48093.html</trackback:ping><description><![CDATA[<p></p> <p>STLPort 5.1.5 下载 <p><a title="http://sourceforge.net/project/showfiles.php?group_id=146814" href="http://sourceforge.net/project/showfiles.php?group_id=146814">http://sourceforge.net/project/showfiles.php?group_id=146814</a> <p>Bat文件 <p>&nbsp; <p>cd c:\Program Files\Microsoft Visual Studio\VC98\bin<br>pause  <p>call VCVARS32.BAT<br>pause  <p>rem cd C:\STLport-5.1.5\STLport-5.1.5\build\Makefiles\nmake<br>cd C:\STLport-5.1.5\STLport-5.1.5\build\lib<br>pause<br>call configure --help<br>pause<br>call configure -c msvc6<br>pause<br>nmake /f msvc.mak<br>nmake /f msvc.mak install  <p>rem nmake -f vc6.mak clean all<br>rem nmake -f vc6.mak install  <p>pause<br>exit</p><img src ="http://www.cppblog.com/woaidongmao/aggbug/48093.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/woaidongmao/" target="_blank">肥仔</a> 2008-04-25 00:56 <a href="http://www.cppblog.com/woaidongmao/archive/2008/04/25/48093.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>boost bat</title><link>http://www.cppblog.com/woaidongmao/archive/2008/04/24/48049.html</link><dc:creator>肥仔</dc:creator><author>肥仔</author><pubDate>Thu, 24 Apr 2008 10:53:00 GMT</pubDate><guid>http://www.cppblog.com/woaidongmao/archive/2008/04/24/48049.html</guid><wfw:comment>http://www.cppblog.com/woaidongmao/comments/48049.html</wfw:comment><comments>http://www.cppblog.com/woaidongmao/archive/2008/04/24/48049.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/woaidongmao/comments/commentRss/48049.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/woaidongmao/services/trackbacks/48049.html</trackback:ping><description><![CDATA[<p>SET INCLUDE=\"D:\\STLport-4.6.2\\stlport\";%INCLUDE%<br>SET LIB=\"D:\\STLport-4.6.2\\lib\";%LIB%<br>SET MSVC_ROOT="C:\Program Files\Microsoft Visual Studio\VC98"<br>SET VISUALC="C:\Program Files\Microsoft Visual Studio\VC98"<br>SET JAM_TOOLSET=VISUALC<br>SET PYTHON_ROOT=C:\Python22<br>SET PYTHON_VERSION=2.2<br>SET STLPORT_PATH=C:\STLport-4.6.2\lib<br>SET STLPORT_VERSION=4.6.2<br>rem pause<br>cd c:\Program Files\Microsoft Visual Studio\VC98\bin<br>pause<br>call VCVARS32.BAT<br>pause<br>cd C:\boost_1_33_1\libs\regex\build<br>pause<br>rem call nmake -f vc6-stlport.mak<br>pause<br>cd C:\boost_1_33_1<br>pause<br>rem bjam -sBOOST_ROOT=. -sTOOLS=msvc --with-thread stage<br>rem msvc-stlport-tools<br>bjam -sBOOST_ROOT=. -sTOOLS=msvc-stlport --with-thread stage<br>rem quit<br>exit  <p>rem 版本：boost 1.33.1 STLport 5.0 / VS.net 2003 没有特殊设置，除了程序的debug build应加_STLP_DEBUG宏定义。<br>rem boost build procedure: <br>SET INCLUDE=\"D:\\STLport_50\\stlport\";%INCLUDE% <br>SET LIB=\"D:\\STLport_50\\lib\";%LIB%  <p>SET PYTHON_ROOT=\"D:\\Python24\" <br>SET PYTHON_VERSION=2.4.2 <br>SET STLPORT_PATH=\"D:\\\" <br>SET STLPORT_50_PATH=\"D:\\STLport_50\" <br>SET STLPORT_VERSION=5.0 <br>SET STLPORT_VERSIONS=5.0 <br>SET VC71_ROOT=\"d:\\Program Files\\Microsoft Visual Studio .NET 2003\\Vc7\"  <p>bjam.exe -sBOOST_ROOT=. -sTOOLS=vc-7_1 stage <br>bjam.exe -sBOOST_ROOT=. -sTOOLS=vc-7_1-stlport stage  <p>如果不编译python库，最后两行改成  <p>bjam.exe -sBOOST_ROOT=. -sTOOLS=vc-7_1 --without-python stage<br>bjam.exe -sBOOST_ROOT=. -sTOOLS=vc-7_1-stlport --without-python stage  <p>pause<br>cd c:\boost_1_33_1<br>pause<br>rem bjam -sBOOST_ROOT=. -sTOOLS=msvc "-sBUILD=debug release static/dynamic<br>pause<br>cd C:\Program Files\Tencent\TM<br>pause<br>start TMShell.exe<br>pause</p><img src ="http://www.cppblog.com/woaidongmao/aggbug/48049.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/woaidongmao/" target="_blank">肥仔</a> 2008-04-24 18:53 <a href="http://www.cppblog.com/woaidongmao/archive/2008/04/24/48049.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>boost 编译</title><link>http://www.cppblog.com/woaidongmao/archive/2008/04/19/47559.html</link><dc:creator>肥仔</dc:creator><author>肥仔</author><pubDate>Fri, 18 Apr 2008 17:55:00 GMT</pubDate><guid>http://www.cppblog.com/woaidongmao/archive/2008/04/19/47559.html</guid><wfw:comment>http://www.cppblog.com/woaidongmao/comments/47559.html</wfw:comment><comments>http://www.cppblog.com/woaidongmao/archive/2008/04/19/47559.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/woaidongmao/comments/commentRss/47559.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/woaidongmao/services/trackbacks/47559.html</trackback:ping><description><![CDATA[<p>Boost历史版本下载地址  <p><a title="http://sourceforge.net/project/showfiles.php?group_id=7586&amp;package_id=8041" href="http://sourceforge.net/project/showfiles.php?group_id=7586&amp;package_id=8041">http://sourceforge.net/project/showfiles.php?group_id=7586&amp;package_id=8041</a>  <p>&nbsp; <p>bat文件，boost 1.33.1 Python 2.2.1,可能需要重新安装stl port, stl port版本有问题&nbsp; <p>::如果不要编译bjam.exe的话<br>rem GOTO install  <p>cd C:\boost_1_33_1\tools\build\jam_src<br>pause<br>call build.bat<br>pause<br>copy C:\boost_1_33_1\tools\build\jam_src\bin.ntx86\bjam.exe C:\boost_1_33_1<br>pause  <p>:install  <p>rem SET INCLUDE=\"C:\\STLport-4.6.2\\stlport\";%INCLUDE%<br>rem SET LIB=\"C:\\STLport-4.6.2\\lib\";%LIB%<br>SET MSVC_ROOT="C:\Program Files\Microsoft Visual Studio\VC98"<br>SET VISUALC="C:\Program Files\Microsoft Visual Studio\VC98"<br>SET JAM_TOOLSET=VISUALC<br>SET PYTHON_ROOT=C:\Python22<br>SET PYTHON_VERSION=2.2<br>SET STLPORT_PATH=C:\STLport-4.6.2\lib<br>SET STLPORT_VERSION=4.6.2<br>cd c:\Program Files\Microsoft Visual Studio\VC98\bin<br>pause  <p>call VCVARS32.BAT<br>pause  <p>cd C:\boost_1_33_1<br>pause  <p>::stage代表 lib<br>::msvc-stlport是msvc-stlport-tools.jam文件，可以搜索得到<br>::--with-thread是只编译thread库，--without-thread则相反<br>::比如编译thread 的lib库如下行.<br>rem bjam -sBOOST_ROOT=. -sTOOLS=msvc --with-thread stage  <p>::编译所有<br>bjam -sBOOST_ROOT=. -sTOOLS=msvc-stlport install<br>bjam -sBOOST_ROOT=. -sTOOLS=msvc install  <p>::编译regex<br>rem bjam -sBOOST_ROOT=. -sTOOLS=msvc-stlport --with-regex install<br>rem bjam -sBOOST_ROOT=. -sTOOLS=msvc --with-regex install  <p>::编译thread<br>rem bjam -sBOOST_ROOT=. -sTOOLS=msvc-stlport --with-thread install<br>rem bjam -sBOOST_ROOT=. -sTOOLS=msvc --with-thread install  <p>pause<br>exit  <p>&nbsp;</p> <p>&nbsp;</p> <p>&nbsp;</p> <p>1、下载python-2.5.2.msi安装到C:\Python25  <p><a href="http://www.python.org/ftp/python/2.5.2/python-2.5.2.msi">http://www.python.org/ftp/python/2.5.2/python-2.5.2.msi</a>  <p>2、下载boost_1_35_0，解压到C:\boost_1_35_0  <p><a href="http://sourceforge.net/project/downloading.php?group_id=7586&amp;use_mirror=nchc&amp;filename=boost_1_35_0.zip&amp;48604828">http://sourceforge.net/project/downloading.php?group_id=7586&amp;use_mirror=nchc&amp;filename=boost_1_35_0.zip&amp;48604828</a>  <p>3、执行C:\boost_1_35_0\tools\jam\build_dist.bat  <p>4、生成了bjam.exe在：C:\boost_1_35_0\tools\jam\src\bin.ntx86\bjam.exe  <p>5、拷贝bjam.exe到C:\boost_1_35_0  <p>6、打开cmd，执行：cd C:\boost_1_35_0  <p>7、执行bjam --toolset=msvc -sPYTHON_ROOT="{C:\Python25}" install  <p>bjam --toolset=msvc-6.0 stdlib=stlport -sPYTHON_ROOT="{C:\Python25}" install  <p>等待半个小时左右  <p>8、将C:\boost_1_35_0\libs文件夹（里面是源代码，lib_source），拷贝到C:\Boost，并更改名为boost_src,这样就成了C:\Boost\boost_src  <p>9、把C:\Boost\include\boost-1_35_0\boost，加入到VC6的Include路径,hpp也是C++的头文件啊！Boost库就是用的这个。  <p>10、将C:\Boost\include\boost-1_35_0\boost和C:\Boost\boost_src，加入到VC6的source路径  <p>11、把C:\Boost\lib，加入到VC6的LIB路径  <p>12、C:\boost_1_35_0这个文件夹可以删除了，如果不想删除，那么C:\boost_1_35_0\bin.v2这个是编译时候的obj等文件，可以删除掉。  <p>运行出现的错误  <p>1、预定义头要加入：,D_STLP_DEBUG,__STL_DEBUG  <p>2、ZM limit 错误：工程-&gt;设置-&gt;C/C++选项卡下面有“工程选项”的一个命令区在命令行的末尾加上/Zm1000，改为/Zm2000也行，是整百的都可以  <p>3、“compiler&nbsp;&nbsp; is&nbsp;&nbsp; out&nbsp;&nbsp; of&nbsp;&nbsp; heap&nbsp;&nbsp; space”，\ZM改成2000(最大了)  <p>4、“Fatal&nbsp;&nbsp; Error&nbsp;&nbsp; C1063”，这个错误是编译器栈溢出，可能是你的程序单个源文件太大了，拆分成小一些的文件试试&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MSDN上：&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Fatal&nbsp;&nbsp; Error&nbsp;&nbsp; C1063&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp; compiler&nbsp;&nbsp; limit&nbsp;&nbsp; :&nbsp;&nbsp; compiler&nbsp;&nbsp; stack&nbsp;&nbsp; overflow&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; The&nbsp;&nbsp; program&nbsp;&nbsp; was&nbsp;&nbsp; too&nbsp;&nbsp; complex,&nbsp;&nbsp; possibly&nbsp;&nbsp; due&nbsp;&nbsp; to&nbsp;&nbsp; recursive&nbsp;&nbsp; include&nbsp;&nbsp; files.&nbsp;&nbsp; Split&nbsp;&nbsp; the&nbsp;&nbsp; code&nbsp;&nbsp; into&nbsp;&nbsp; smaller&nbsp;&nbsp; source&nbsp;&nbsp; files&nbsp;&nbsp; and&nbsp;&nbsp; recompile.  <p>手动编译boost::regex  <p>1、cmd;  <p>2、cd C:\boost_1_35_0\libs\regex\build  <p>3、vcvars32.bat  <p>4、SET STLPORT_PATH=C:\STLport\lib(如果需要以STLPort编译的话)  <p>5、nmake -f vc6-stlport.mak（STLPort编译）或者 nmake -f vc6.mak（普通编译）  <p>用来测试的代码，建立一个Win32 Console Application：  <p>#include "stdafx.h"<br>#include &lt;iostream&gt;<br>#include &lt;boost/regex.hpp&gt;<br>#include &lt;boost/thread.hpp&gt;<br>int main() <br>{&nbsp; <br>&nbsp;&nbsp;&nbsp; // 3 digits, a word, any character, 2 digits or "N/A",&nbsp; <br>&nbsp;&nbsp;&nbsp; // a space, then the first word again <br>&nbsp;&nbsp;&nbsp; boost::regex reg("\\d{3}([a-zA-Z]+).(\\d{2}|N/A)\\s\\1");&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; std::string correct="123Hello N/A Hello";&nbsp; <br>&nbsp;&nbsp;&nbsp; std::string incorrect="123Hello 12 hello";&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; assert(boost::regex_match(correct,reg)==true);&nbsp; <br>&nbsp;&nbsp;&nbsp; assert(boost::regex_match(incorrect,reg)==false);<br>&nbsp;&nbsp;&nbsp; boost::regex reg1("(new)|(delete)");<br>&nbsp;&nbsp;&nbsp; boost::smatch m;std::string s=&nbsp; "Calls to new must be followed by delete. \&nbsp; Calling simply new results in a leak!";<br>&nbsp;&nbsp;&nbsp; if (boost::regex_search(s,m,reg1)) <br>&nbsp;&nbsp;&nbsp; {&nbsp; // Did new match?&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (m[1].matched)&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; std::cout &lt;&lt; "The expression (new) matched!\n";&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (m[2].matched)&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; std::cout &lt;&lt; "The expression (delete) matched!\n";<br>&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; return 0;<br>}  <p>如果一切顺利通过，恭喜你，boost安装成功。  <h5><a href="http://cpp-circle.group.javaeye.com/group/blog/67715">vc6 上安装stlport和boost库</a></h5> <p><a href="http://zzsczz.javaeye.com"><img title="zzsczz的博客: zzsczz" alt="用户头像" src="http://www.javaeye.com/images/user-logo-thumb.gif?1194185304"></a>  <p>1 <br>vc 6&nbsp;&nbsp; sp5补丁&nbsp; 预处理补丁<br>python2.2.3<br>stlport4.5.3 <br>boost1.3.0.2<br>2<br>使用stlport的iostream，boost.python编译失败<br>如果禁用stlportt的iostream，boost.regex编译失败<br>选择boost1.3.0.2的原因:<br>从<br><a href="http://engineering.meta-comm.com/boost.aspx">http://engineering.meta-comm.com/boost.aspx</a><br>得知Boost-wide regression reports<br>vc6基本支持boost1.3.0.2 的全部库<br>而boost以后的版本，vc6 的表现可以说是惨不忍睹。<br>boost1.3.0.2支持 python2.2 stlport 4.5.3<br>基本就是这个样子了。</p><img src ="http://www.cppblog.com/woaidongmao/aggbug/47559.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/woaidongmao/" target="_blank">肥仔</a> 2008-04-19 01:55 <a href="http://www.cppblog.com/woaidongmao/archive/2008/04/19/47559.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>