﻿<?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++博客-shifan3-随笔分类-C++</title><link>http://www.cppblog.com/shifan3/category/3013.html</link><description>Everything is template...</description><language>zh-cn</language><lastBuildDate>Tue, 20 May 2008 22:42:04 GMT</lastBuildDate><pubDate>Tue, 20 May 2008 22:42:04 GMT</pubDate><ttl>60</ttl><item><title>神意不是凡人能领会的（1）</title><link>http://www.cppblog.com/shifan3/archive/2007/11/02/35767.html</link><dc:creator>shifan3</dc:creator><author>shifan3</author><pubDate>Fri, 02 Nov 2007 10:05:00 GMT</pubDate><guid>http://www.cppblog.com/shifan3/archive/2007/11/02/35767.html</guid><wfw:comment>http://www.cppblog.com/shifan3/comments/35767.html</wfw:comment><comments>http://www.cppblog.com/shifan3/archive/2007/11/02/35767.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.cppblog.com/shifan3/comments/commentRss/35767.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/shifan3/services/trackbacks/35767.html</trackback:ping><description><![CDATA[转载自神的blog<br><a href="http://blog.csdn.net/vbvan/archive/2007/10/30/1857134.aspx">http://blog.csdn.net/vbvan/archive/2007/10/30/1857134.aspx</a><br><br><span style="FONT-SIZE: 24pt"><font color=#000080>Flexible C++</font><br></span><br>C++是一门非常灵活的语言，只要充分发挥你的想象， 再普通的东西都能玩出新花样<br><br>1、1~1000求和<br>循环？递归？再简单不过的题目了。但是如果不允许你用判断语句呢？<br>如果你熟悉switch的内部实现，那么你很容易想到使用函数指针数组。<br>
<p align=left><span>#include</span><span> <span>&lt;cstdio&gt;</span></span></p>
<p><span>typedef</span><span> <span>int</span> (*<span>fun</span>)(<span>int</span>);<br></span><span>int</span><span> <span>f1</span>(<span>int</span> <span>i</span>) {<span>return</span> 0;}</span><br><span>int</span><span> <span>f2</span>(<span>int</span> <span>i</span>) {<span>fun</span> <span>f</span>[2]={<span>f1</span>,<span>f2</span>}; <span>return</span> <span>i</span>+<span>f</span>[!!<span>i</span>](<span>i</span>-1);}</span><br><span>int</span><span> <span>main</span>()<br>{<br><span>&nbsp;&nbsp;&nbsp;&nbsp; </span><span>printf</span>(<span>"%d\n"</span>,<span>f2</span>(1000));<br>}</span></p>
2、输出1,2,...,100,99,...,2,1<br>如果同样不让你用判断语句呢？你仍然可以使用函数指针数组：<br>
<p align=left><span>#include</span><span> <span>&lt;cstdio&gt;</span></span></p>
<p align=left><span>typedef</span><span> <span>void</span> (*<span>fun</span>)(<span>int</span> <span>i</span>,<span>int</span> <span>n</span>);&nbsp;<br></span><span>void</span><span> <span>f1</span>(<span>int</span> <span>i</span>,<span>int</span> <span>n</span>);</span><br><span>void</span><span> <span>f2</span>(<span>int</span> <span>i</span>,<span>int</span> <span>n</span>);</span><br><span>void</span><span> <span>f3</span>(<span>int</span> <span>i</span>,<span>int</span> <span>n</span>);</span></p>
<p align=left><span>void</span><span> <span>f1</span>(<span>int</span> <span>i</span>,<span>int</span> <span>n</span>)<br>{<br><span>&nbsp;&nbsp;&nbsp;&nbsp; </span><span>fun</span> <span>f</span>[2]={<span>f1</span>,<span>f2</span>};</span></p>
<p align=left><span><span>&nbsp; &nbsp;&nbsp; </span><span>printf</span>(<span>"%d\n"</span>,<span>i</span>);<br><span>&nbsp;&nbsp;&nbsp;&nbsp; </span><span>f</span>[<span>i</span>+1==<span>n</span>](<span>i</span>+1,<span>n</span>);<br>}</span><br><span>void</span><span> <span>f2</span>(<span>int</span> <span>i</span>,<span>int</span> <span>n</span>)<br>{<br><span>&nbsp;&nbsp;&nbsp;&nbsp; </span><span>fun</span> <span>f</span>[2]={<span>f2</span>,<span>f3</span>};<br><span>&nbsp;&nbsp;&nbsp;&nbsp; </span><span>printf</span>(<span>"%d\n"</span>,<span>i</span>);<br><span>&nbsp;&nbsp;&nbsp;&nbsp; </span><span>f</span>[<span>i</span>==1](<span>i</span>-1,<span>n</span>);<br>}</span><br><span>void</span><span> <span>f3</span>(<span>int</span> <span>i</span>,<span>int</span> <span>n</span>) {}</span></p>
<p><span>int</span><span> <span>main</span>()<br>{<br><span>&nbsp;&nbsp;&nbsp;&nbsp; </span><span>f1</span>(1,100);<br>}</span></p>
不过我们有更简洁的方法。<br>短路算法和逗号表达式粉墨登场了，一行搞定~<br>
<p align=left><span>#include</span><span> <span>&lt;cstdio&gt;</span></span></p>
<p align=left><span>void</span><span> <span>f</span>(<span>int</span> <span>i</span>,<span>int</span> <span>n</span>)<br>{<br><span>&nbsp;&nbsp;&nbsp;&nbsp; </span><span>printf</span>(<span>"%d\n"</span>,<span>i</span>),(<span>i</span>&lt;<span>n</span>)&amp;&amp;(<span>f</span>(<span>i</span>+1,<span>n</span>),<span>printf</span>(<span>"%d\n"</span>,<span>i</span>));<br>}</span></p>
<p><span>int</span><span> <span>main</span>()<br>{<br><span>&nbsp;&nbsp;&nbsp;&nbsp; </span><span>f</span>(1,100);<br>}</span></p>
<img src ="http://www.cppblog.com/shifan3/aggbug/35767.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/shifan3/" target="_blank">shifan3</a> 2007-11-02 18:05 <a href="http://www.cppblog.com/shifan3/archive/2007/11/02/35767.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[yc]用户态非抢占式线程库实现</title><link>http://www.cppblog.com/shifan3/archive/2007/03/16/19968.html</link><dc:creator>shifan3</dc:creator><author>shifan3</author><pubDate>Fri, 16 Mar 2007 08:33:00 GMT</pubDate><guid>http://www.cppblog.com/shifan3/archive/2007/03/16/19968.html</guid><wfw:comment>http://www.cppblog.com/shifan3/comments/19968.html</wfw:comment><comments>http://www.cppblog.com/shifan3/archive/2007/03/16/19968.html#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://www.cppblog.com/shifan3/comments/commentRss/19968.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/shifan3/services/trackbacks/19968.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 平台 i386 ， win32 ， msvc 2003 &nbsp; 代码简单介绍： &nbsp; 调度算法：轮转法。。，可修改 &nbsp; 内存模型：每个线程拥有各自独立的堆栈。启动线程的时候，切换到对应的堆栈再启动，使得线程之间的堆栈互不干扰 &nbsp; 调度方式：线程调用 schedule 函数， schedule 用 setjmp 保存当前堆栈，选择一个...&nbsp;&nbsp;<a href='http://www.cppblog.com/shifan3/archive/2007/03/16/19968.html'>阅读全文</a><img src ="http://www.cppblog.com/shifan3/aggbug/19968.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/shifan3/" target="_blank">shifan3</a> 2007-03-16 16:33 <a href="http://www.cppblog.com/shifan3/archive/2007/03/16/19968.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[yc]垃圾回收？C++资源管理杂谈</title><link>http://www.cppblog.com/shifan3/archive/2007/01/24/17963.html</link><dc:creator>shifan3</dc:creator><author>shifan3</author><pubDate>Wed, 24 Jan 2007 10:02:00 GMT</pubDate><guid>http://www.cppblog.com/shifan3/archive/2007/01/24/17963.html</guid><wfw:comment>http://www.cppblog.com/shifan3/comments/17963.html</wfw:comment><comments>http://www.cppblog.com/shifan3/archive/2007/01/24/17963.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.cppblog.com/shifan3/comments/commentRss/17963.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/shifan3/services/trackbacks/17963.html</trackback:ping><description><![CDATA[<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">说到</span> <span lang=EN-US><font face=Calibri>C/C++</font> </span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">的资源管理，人人都会头痛半天。自从</span> <span lang=EN-US><font face=Calibri>C++0x</font> </span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">（就是</span> <span lang=EN-US><font face=Calibri>C++09</font> </span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">了）标准漏出风声之后，</span> <span lang=EN-US><font face=Calibri>C++</font> </span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">标准是否会引入自动垃圾回收机制就成为了众多</span> <span lang=EN-US><font face=Calibri>C++</font> </span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">爱好者谈论的话题。但是实际上，在</span> <span lang=EN-US><font face=Calibri>C++</font> </span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">标准的探索上，垃圾回收一直处在一个十分低下的地位。造成其这一处境的原因很多，也很复杂。我们来看看站在</span> <span lang=EN-US><font face=Calibri>C++</font> </span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">程序员的角度上看，资源管理机制现在所面临的局势。</span> </p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">从系统结构上来讲，</span> <span lang=EN-US><font face=Calibri>C/C++</font> </span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">支持</span> <span lang=EN-US><font face=Calibri>3</font> </span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">种内存管理方式，基于栈的自动管理，基于堆的动态管理，和基于全局区的静态管理。由于</span> <span lang=EN-US><font face=Calibri>RAII</font> </span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">的理念，对于</span> <span lang=EN-US><font face=Calibri>C++</font> </span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">来说，内存管理和其他资源管理本质上没有区别。因此对于资源而言，也就自然的拥有这样</span> <span lang=EN-US><font face=Calibri>3</font> </span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">种管理方式。</span> </p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">首先简要的介绍一下</span> <span lang=EN-US><font face=Calibri>RAII</font> </span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">。</span> <span lang=EN-US><font face=Calibri>RAII</font> </span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">的全称是</span> <span lang=EN-US><font face=Calibri>Resource Acquisition Is initialization</font> </span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">。这个思想的基本手法是对于一种想要使用的资源，为其书写一个</span> <span lang=EN-US><font face=Calibri>guard</font> </span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">类，在该类的构造函数里进行资源的请求，在析构函数里进行资源的释放。例如假设我们想管理一个互斥锁，可能的方式是：</span> </p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-font-kerning: 0pt"><o:p></o:p></span></p>
<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">
<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">struct</span> <span style="COLOR: #000000">&nbsp;lock_guard<br><img id=Codehighlighter1_18_83_Open_Image onclick="this.style.display='none'; Codehighlighter1_18_83_Open_Text.style.display='none'; Codehighlighter1_18_83_Closed_Image.style.display='inline'; Codehighlighter1_18_83_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_18_83_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_18_83_Closed_Text.style.display='none'; Codehighlighter1_18_83_Open_Image.style.display='inline'; Codehighlighter1_18_83_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align=top></span> <span id=Codehighlighter1_18_83_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_18_83_Open_Text><span style="COLOR: #000000">{<br><img id=Codehighlighter1_40_48_Open_Image onclick="this.style.display='none'; Codehighlighter1_40_48_Open_Text.style.display='none'; Codehighlighter1_40_48_Closed_Image.style.display='inline'; Codehighlighter1_40_48_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_40_48_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_40_48_Closed_Text.style.display='none'; Codehighlighter1_40_48_Open_Image.style.display='inline'; Codehighlighter1_40_48_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;lock_guard()</span> <span id=Codehighlighter1_40_48_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_40_48_Open_Text><span style="COLOR: #000000">{</span> <span style="COLOR: #0000ff">lock</span> <span style="COLOR: #000000">();}</span> </span><span style="COLOR: #000000"><br><img id=Codehighlighter1_71_81_Open_Image onclick="this.style.display='none'; Codehighlighter1_71_81_Open_Text.style.display='none'; Codehighlighter1_71_81_Closed_Image.style.display='inline'; Codehighlighter1_71_81_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top> <img id=Codehighlighter1_71_81_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_71_81_Closed_Text.style.display='none'; Codehighlighter1_71_81_Open_Image.style.display='inline'; Codehighlighter1_71_81_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span> <span style="COLOR: #000000">~</span> <span style="COLOR: #000000">lock_guard()</span> <span id=Codehighlighter1_71_81_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_71_81_Open_Text><span style="COLOR: #000000">{unlock();}</span> </span><span style="COLOR: #000000"><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></span> </div>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><br>&nbsp;&nbsp;&nbsp;&nbsp; 此后，对这个对象使用什么内存管理方式，也就等价于对这个互斥锁使用什么内存管理方式。</p>
</span>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US><span style="mso-tab-count: 1"><font face=Calibri>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </font></span></span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">借助于</span> <span lang=EN-US><font face=Calibri>RAII</font> </span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">，以后我们可以只讨论内存资源的管理方式，其它资源的管理方式可以使用</span> <span lang=EN-US><font face=Calibri>RAII</font> </span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">来同样的实现。现在我们已经很自然的获得了资源管理的</span> <span lang=EN-US><font face=Calibri>3</font> </span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">种方式：基于堆的动态方式、基于栈的自动方式和全局。值得一提的是，这</span> <span lang=EN-US><font face=Calibri>3</font> </span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">种方式中比较不容易出错的后两种实际上可以解决大部分的资源管理需求。因为绝大部分资源，都属于获取</span> <span lang=EN-US><font face=Calibri>-</font> </span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">使用</span> <span lang=EN-US><font face=Calibri>-</font> </span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">释放型的，例如很多同步对象，文件锁，</span> <span lang=EN-US><font face=Calibri>WinGDI</font> </span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">里的许多</span> <span lang=EN-US><font face=Calibri>GDI</font> </span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">对象。我们缺乏管理的，只有那些一次获得，多个环境拥有，并且只能有一次释放的少数资源。</span> </p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US><span style="mso-tab-count: 1"><font face=Calibri>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </font></span></span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">回到内存模型来看，有一点让我们无法将内存与其它资源等同（反过来，把其它资源和内存等同却是可以的），那就是循环引用。</span> <span lang=EN-US><font face=Calibri>A</font> </span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">内存可以持有指向</span> <span lang=EN-US><font face=Calibri>B</font> </span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">内存的引用，</span> <span lang=EN-US><font face=Calibri>B</font> </span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">内存也可以反过来持有</span> <span lang=EN-US><font face=Calibri>A</font> </span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">内存的引用。循环引用导致内存管理不可以用&#8220;是否有指向该内存的引用&#8221;来区分一块内存是否可以回收。从而丧失了一个绝佳的管理手段。但是在没有循环引用的场合下，我们还是有非常简洁高效的管理方法的。那就是引用计数。</span> </p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US><span style="mso-tab-count: 1"><font face=Calibri>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </font></span></span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">引用计数是在没有循环引用场合下进行内存管理的绝佳手段，它具有轻量、高效、即时、可控的优点。而且在</span> <span lang=EN-US><font face=Calibri>C++</font> </span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">里，引用计数已经非常成熟，只需要使用</span> <span lang=EN-US><font face=Calibri>boost.shared_ptr</font> </span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">或者其它非官方的引用计数指针库就可以了，而且据悉</span> <span lang=EN-US><font face=Calibri>C++09</font> </span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">很可能把</span> <span lang=EN-US><font face=Calibri>boost.shared_ptr</font> </span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">纳入标准库。引用计数的原则是，如果一个对象没有别的指针或引用来指向它，那么这个对象就是可以释放的。具体的手法有大把大把的资料可以查阅，这里就不详细说明了。引用计数通常可以处理哪些场合的资源管理问题呢？首先，对于单方向的资源管理，也就是多个</span> <span lang=EN-US><font face=Calibri>A</font> </span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">的实体拥有</span> <span lang=EN-US><font face=Calibri>1</font> </span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">个</span> <span lang=EN-US><font face=Calibri>B</font> </span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">，然而</span> <span lang=EN-US><font face=Calibri>B</font> </span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">并不会反过来依赖于</span> <span lang=EN-US><font face=Calibri>A</font> </span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">（例如多个对象共享一个日志），引用计数是非常合适的。其次，对于拥有</span> <span lang=EN-US><font face=Calibri>-</font> </span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">反作用的场合，也就是</span> <span lang=EN-US><font face=Calibri>1</font> </span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">个或多个</span> <span lang=EN-US><font face=Calibri>A</font> </span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">的实体拥有</span> <span lang=EN-US><font face=Calibri>1</font> </span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">个或多个</span> <span lang=EN-US><font face=Calibri>B</font> </span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">，而</span> <span lang=EN-US><font face=Calibri>B</font> </span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">也拥有这些</span> <span lang=EN-US><font face=Calibri>A</font> </span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">的实体的引用，但是</span> <span lang=EN-US><font face=Calibri>B</font> </span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">的生存期仍然决定于</span> <span lang=EN-US><font face=Calibri>A</font> </span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">的生存期（例如父窗口拥有若干子窗口，子窗口也具有</span> <span lang=EN-US><font face=Calibri>parent</font> </span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">指针指向父窗口，但是子窗口的生存期决定于父窗口的生存期），这个时候</span> <span lang=EN-US><font face=Calibri>A</font> </span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">可以对</span> <span lang=EN-US><font face=Calibri>B</font> </span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">使用引用计数指针，而</span> <span lang=EN-US><font face=Calibri>B</font> </span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">可以对</span> <span lang=EN-US><font face=Calibri>A</font> </span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">使用原生的普通指针，同样的可以很好的解决问题。</span> </p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US><span style="mso-tab-count: 1"><font face=Calibri>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </font></span></span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">现在所剩下的，就只有生存期的循环依赖了。如果</span> <span lang=EN-US><font face=Calibri>AB</font> </span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">互相持有对方的引用，而且</span> <span lang=EN-US><font face=Calibri>AB</font> </span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">互相的存在都依赖于对方，这样引用计数就无法解决了。但是如果仔细想一下就会发现，这种情况在</span> <span lang=EN-US><font face=Calibri>C++</font> </span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">里几乎不可能存在。生存期循环依赖只有</span> <span lang=EN-US><font face=Calibri>2</font> </span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">种后果，要么</span> <span lang=EN-US><font face=Calibri>A</font> </span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">和</span> <span lang=EN-US><font face=Calibri>B</font> </span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">的析构函数里互相析构（当然就挂了），要么互相都不析构（当然就泄露了）。而这两种都是在正常编程中不会出现的情况。所以如果即使仅仅使用引用计数，我们也可以解决几乎所有的资源管理问题。</span> </p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">现在还剩下那么一丁点极少出现的不能处理的情况，我们可以使用更加复杂的</span> <span lang=EN-US><font face=Calibri>gc</font> </span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">来实现。可惜的是，实现一个</span> <span lang=EN-US><font face=Calibri>gc</font> </span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">所要耗费的精力实在太大，而且几乎不可避免的要成为侵入式的库。所以有点得不偿失。而且</span> <span lang=EN-US><font face=Calibri>gc</font> </span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">通常会产生更多的毛病：</span> </p>
<p class=MsoListParagraph style="MARGIN: 0cm 0cm 0pt 57.75pt; TEXT-INDENT: -36.75pt; mso-char-indent-count: 0; mso-list: l0 level1 lfo1"><span lang=EN-US style="mso-fareast-font-family: Calibri; mso-fareast-theme-font: minor-latin; mso-bidi-font-family: Calibri; mso-bidi-theme-font: minor-latin"><span style="mso-list: Ignore"><font face=Calibri>1．</font> <span style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">你无法却知对象析构的具体时间，从而无法真正知道影响程序性能的瓶颈在什么地方。</span> </p>
<p class=MsoListParagraph style="MARGIN: 0cm 0cm 0pt 57.75pt; TEXT-INDENT: -36.75pt; mso-char-indent-count: 0; mso-list: l0 level1 lfo1"><span lang=EN-US style="mso-fareast-font-family: Calibri; mso-fareast-theme-font: minor-latin; mso-bidi-font-family: Calibri; mso-bidi-theme-font: minor-latin"><span style="mso-list: Ignore"><font face=Calibri>2．</font> <span style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span><span lang=EN-US><font face=Calibri>gc</font> </span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">都倾向于大量的使用内存，直到内存不够的时候再进行清理，这样会导致程序的内存用量严重颠簸，并且产生大量的换页。</span> </p>
<p class=MsoListParagraph style="MARGIN: 0cm 0cm 0pt 57.75pt; TEXT-INDENT: -36.75pt; mso-char-indent-count: 0; mso-list: l0 level1 lfo1"><span lang=EN-US style="mso-fareast-font-family: Calibri; mso-fareast-theme-font: minor-latin; mso-bidi-font-family: Calibri; mso-bidi-theme-font: minor-latin"><span style="mso-list: Ignore"><font face=Calibri>3．</font> <span style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">过度的依赖于</span> <span lang=EN-US><font face=Calibri>gc</font> </span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">会使程序员大量的把可以由之前提到的各种方法来处理的资源交给</span> <span lang=EN-US><font face=Calibri>gc</font> </span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">来处理，无故的加重了</span> <span lang=EN-US><font face=Calibri>gc</font> </span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">的负担。</span> </p>
<p class=MsoListParagraph style="MARGIN: 0cm 0cm 0pt 57.75pt; TEXT-INDENT: -36.75pt; mso-char-indent-count: 0; mso-list: l0 level1 lfo1"><span lang=EN-US style="mso-fareast-font-family: Calibri; mso-fareast-theme-font: minor-latin; mso-bidi-font-family: Calibri; mso-bidi-theme-font: minor-latin"><span style="mso-list: Ignore"><font face=Calibri>4．</font> <span style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span><span lang=EN-US><font face=Calibri>gc</font> </span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">的管理方法和</span> <span lang=EN-US><font face=Calibri>C++</font> </span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">的析构函数有可能产生语义上的冲突。</span> </p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt"><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">这就是为什么</span> <span lang=EN-US><font face=Calibri>C++</font> </span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">标准对垃圾回收的态度如此恶劣的原因。</span> </p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US><o:p><font face=Calibri>&nbsp;</font> </o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">我们现在回过头来看</span> <span lang=EN-US><font face=Calibri>Java/C#</font> </span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">这样的内置</span> <span lang=EN-US><font face=Calibri>gc</font> </span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">的语言。这样的语言由于使用了</span> <span lang=EN-US><font face=Calibri>gc</font> </span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">，就不可避免的放弃了析构函数。为什么</span> <span lang=EN-US><font face=Calibri>gc</font> </span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">会和析构函数产生冲突呢？一个</span> <span lang=EN-US><font face=Calibri>gc</font> </span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">一般会希望在进行垃圾回收的时候，整个过程是一个原子的，但析构函数会破坏这一点，在释放内存的时候如果还要执行代码，那么难免会对整个</span> <span lang=EN-US><font face=Calibri>gc</font> </span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">环境产生破坏性的影响。由于没有析构函数，这些语言就不可能做到</span> <span lang=EN-US><font face=Calibri>RAII</font> </span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">，也就是说，它们的</span> <span lang=EN-US><font face=Calibri>gc</font> </span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">所能够管理的，也就仅仅只有内存而已了。对于其他资源，</span> <span lang=EN-US><font face=Calibri>Java</font> </span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">等就必须手动释放。虽然</span> <span lang=EN-US><font face=Calibri>C#</font> </span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">提供了</span> <span lang=EN-US><font face=Calibri>with</font> </span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">关键字来缓解这一问题，但仍然无法彻底的解决。</span> </p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">还有什么麻烦呢？之前说的那</span> <span lang=EN-US><font face=Calibri>4</font> </span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">点全部都有。虽然</span> <span lang=EN-US><font face=Calibri>JVM</font> </span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">的速度在不断的提高，但是内存使用这一点却完全没有发展，不能不说是</span> <span lang=EN-US><font face=Calibri>gc</font> </span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">说导致。它所带来了什么好处呢？是内存管理的自动化，而不是资源管理的自动化。</span> </p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span lang=EN-US><o:p><font face=Calibri>&nbsp;</font> </o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">所以说</span> <span lang=EN-US><font face=Calibri>C++</font> </span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">并不是世人所想象的那样需要</span> <span lang=EN-US><font face=Calibri>gc</font> </span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">，</span> <span lang=EN-US><font face=Calibri>C++</font> </span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">本身就已经提供了足够强大的资源管理能力。基于栈的自动管理，或者使用引用计数，几乎可以达到和</span> <span lang=EN-US><font face=Calibri>gc</font> </span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">同样的覆盖面，而且没有</span> <span lang=EN-US><font face=Calibri>gc</font> </span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">的那些问题，</span> <span lang=EN-US><font face=Calibri>RAII</font> </span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">使得</span> <span lang=EN-US><font face=Calibri>C++</font> </span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">在管理非内存资源的时候还更加有优势，为什么不使用呢？<br><br></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US><o:p><font face=Calibri>&nbsp;</font> </o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US><font face=Calibri>ps. </font></span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">设计一个非官方的</span> <span lang=EN-US><font face=Calibri>gc</font> </span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: 宋体; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin">库还是可以的。但是毕竟不会成为主流了。</span> </p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"></p>
<img src ="http://www.cppblog.com/shifan3/aggbug/17963.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/shifan3/" target="_blank">shifan3</a> 2007-01-24 18:02 <a href="http://www.cppblog.com/shifan3/archive/2007/01/24/17963.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[yc]详解link</title><link>http://www.cppblog.com/shifan3/archive/2007/01/05/17325.html</link><dc:creator>shifan3</dc:creator><author>shifan3</author><pubDate>Fri, 05 Jan 2007 08:03:00 GMT</pubDate><guid>http://www.cppblog.com/shifan3/archive/2007/01/05/17325.html</guid><wfw:comment>http://www.cppblog.com/shifan3/comments/17325.html</wfw:comment><comments>http://www.cppblog.com/shifan3/archive/2007/01/05/17325.html#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://www.cppblog.com/shifan3/comments/commentRss/17325.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/shifan3/services/trackbacks/17325.html</trackback:ping><description><![CDATA[详解link<br>有些人写C/C++(以下假定为C++)程序，对unresolved external link或者duplicated external simbol的错误信息不知所措（因为这样的错误信息不能定位到某一行）。或者对语言的一些部分不知道为什么要（或者不要）这样那样设计。了解本文之后，或许会有一些答案。<br>&nbsp;&nbsp;&nbsp; 首先看看我们是如何写一个程序的。如果你在使用某种IDE（Visual Studio，Elicpse，Dev C++等），你可能不会发现程序是如何组织起来的（很多人因此而反对初学者使用IDE）。因为使用IDE，你所做的事情，就是在一个项目里新建一系列的.cpp和.h文件，编写好之后在菜单里点击&#8220;编译&#8221;，就万事大吉了。但其实以前，程序员写程序不是这样的。他们首先要打开一个编辑器，像编写文本文件一样的写好代码，然后在命令行下敲<br>&nbsp;&nbsp; &nbsp;cc 1.cpp -o 1.o<br>&nbsp;&nbsp; &nbsp;cc 2.cpp -o 2.o<br>&nbsp;&nbsp; &nbsp;cc 3.cpp -o 3.o<br>这里cc代表某个C/C++编译器，后面紧跟着要编译的cpp文件，并且以-o指定要输出的文件（请原谅我没有使用任何一个流行编译器作为例子）。这样当前目录下就会出现：<br>&nbsp;&nbsp; &nbsp;1.o 2.o 3.o<br>最后，程序员还要键入<br>&nbsp;&nbsp; &nbsp;link 1.o 2.o 3.o -o a.out<br>来生成最终的可执行文件a.out。现在的IDE，其实也同样遵照着这个步骤，只不过把一切都自动化了。<br>&nbsp;&nbsp;&nbsp; 让我们来分析上面的过程，看看能发现什么。<br>&nbsp;&nbsp;&nbsp; 首先，对源代码进行编译，是对各个cpp文件单独进行的。对于每一次编译，如果排除在cpp文件里include别的cpp文件的情况（这是C++代码编写中极其错误的写法），那么编译器仅仅知道当前要编译的那一个cpp文件，对其他的cpp文件的存在完全不知情。<br>&nbsp;&nbsp;&nbsp; 其次，每个cpp文件编译后，产生的.o文件，要被一个链接器(link)所读入，才能最终生成可执行文件。<br>&nbsp;&nbsp;&nbsp; 好了，有了这些感性认识之后，让我们来看看C/C++程序是如何组织的。<br>&nbsp;&nbsp; &nbsp;<br>&nbsp;&nbsp;&nbsp; 首先要知道一些概念：<br>&nbsp;&nbsp;&nbsp; 编译：编译器对源代码进行编译，是将以文本形式存在的源代码翻译为机器语言形式的目标文件的过程。<br>&nbsp;&nbsp;&nbsp; 编译单元：对于C++来说，每一个cpp文件就是一个编译单元。从之前的编译过程的演示可以看出，各个编译单元之间是互相不可知的。<br>&nbsp;&nbsp;&nbsp; 目标文件：由编译所生成的文件，以机器码的形式包含了编译单元里所有的代码和数据，以及一些其他的信息。<br>&nbsp;&nbsp; &nbsp;<br>&nbsp;&nbsp;&nbsp; 下面我们具体看看编译的过程。我们跳过语法分析等，直接来到目标文件的生成。假设我们有一个1.cpp文件<br>&nbsp;&nbsp;&nbsp; &nbsp;int n = 1;<br><br>&nbsp;&nbsp; &nbsp;void f()<br>&nbsp;&nbsp;&nbsp; &nbsp;{<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;++n;<br>&nbsp;&nbsp; &nbsp;}<br><br>&nbsp;&nbsp;&nbsp; 它编译出来的目标文件1.o就会有一个区域（假定名称为2进制段），包含了以上数据／函数，其中有n, f，以文件偏移量的形式给出很可能就是：<br>&nbsp;&nbsp; &nbsp;偏移量&nbsp;&nbsp; &nbsp;内容&nbsp;&nbsp; &nbsp;长度<br>&nbsp;&nbsp; &nbsp;0x000&nbsp;&nbsp; &nbsp;n&nbsp;&nbsp; &nbsp;4<br>&nbsp;&nbsp; &nbsp;0x004&nbsp;&nbsp; &nbsp;f &nbsp;&nbsp; &nbsp;??<br>&nbsp;&nbsp;&nbsp; 注意：这仅仅是猜测，不代表目标文件的真实布局。目标文件的各个数据不一定连续，也不一定按照这个顺序，当然也不一定从0x000开始。<br>&nbsp;&nbsp;&nbsp; 现在我们看看从0x004开始f函数的内容（在0x86平台下的猜测）：<br>&nbsp;&nbsp; &nbsp;0x004 inc DWORD PTR [0x000]<br>&nbsp;&nbsp; &nbsp;0x00? ret<br>&nbsp;&nbsp;&nbsp; 注意n++已经被翻译为：inc DWORD PTR [0x000]，也就是把本单元0x000位置上的一个DWORD(4字节)加1。<br>&nbsp;&nbsp; &nbsp;<br>&nbsp;&nbsp;&nbsp; 下面如果有另一个2.cpp，如下<br>&nbsp;&nbsp; &nbsp;extern int n;<br>&nbsp;&nbsp; &nbsp;void g()<br>&nbsp;&nbsp; &nbsp;{<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;++n;<br>&nbsp;&nbsp; &nbsp;}<br>&nbsp;&nbsp;&nbsp; 那么它的目标文件2.o的2进制段就应该是<br>&nbsp;&nbsp; &nbsp;偏移量&nbsp;&nbsp; &nbsp;内容&nbsp;&nbsp; &nbsp;长度<br>&nbsp;&nbsp; &nbsp;0x000&nbsp;&nbsp; &nbsp;g &nbsp;&nbsp; &nbsp;??<br>&nbsp;&nbsp;&nbsp; 为什么这里没有n的空间（也就是n的定义），因为n被声明为extern，表明n的定义在别的编译单元里。别忘了编译的时候是不可能知道别的编译单元的情况的，故编译器不知道n究竟在何处，所以这个时候g的二进制代码里没有办法填写inc DWORD PTR [???]中的？？？部分。怎么办呢？这个工作就只能交给后来的链接器去处理。为了让链接器知道哪些地方的地址是没有填好的，所以目标文件还要有一个&#8220;未解决符号表&#8221;，也就是unresolved symbol table. 同样,提供n的定义的目标文件(也就是1.o)也要提供一个&#8220;导出符号表&#8221;，export symbol table, 来告诉链接器自己可以提供哪些地址。<br>&nbsp;&nbsp;&nbsp; 让我们理一下思路：现在我们知道，每一个目标文件，除了拥有自己的数据和二进制代码之外，还要至少提供2个表：未解决符号表和导出符号表，分别告诉链接器自己需要什么和能够提供什么。下面的问题是，如何在2个表之间建立对应关系。这里就有一个新的概念：符号。在C/C++中，每一个变量和函数都有自己的符号。例如变量n的符号就是&#8220;n&#8221;。函数的符号要更加复杂，它需要结合函数名及其参数和调用惯例等，得到一个唯一的字符串。f的符号可能就是"_f"（根据不同编译器可以有变化）。<br>&nbsp;&nbsp;&nbsp; 所以，1.o的导出符号表就是<br>&nbsp;&nbsp; &nbsp;符号&nbsp;&nbsp; &nbsp;地址<br>&nbsp;&nbsp; &nbsp;n&nbsp;&nbsp; &nbsp;0x000<br>&nbsp;&nbsp; &nbsp;_f&nbsp;&nbsp; &nbsp;0x004<br>&nbsp;&nbsp;&nbsp; 而未解决符号表为空<br>&nbsp;&nbsp;&nbsp; 2.o的导出符号表为<br>&nbsp;&nbsp; &nbsp;符号&nbsp;&nbsp; &nbsp;地址<br>&nbsp;&nbsp; &nbsp;_g&nbsp;&nbsp; &nbsp;0x000<br>&nbsp;&nbsp;&nbsp; 未解决符号表为<br>&nbsp;&nbsp; &nbsp;符号&nbsp;&nbsp; &nbsp;地址&nbsp;&nbsp; &nbsp;<br>&nbsp;&nbsp; &nbsp;n&nbsp;&nbsp; &nbsp;0x001&nbsp;&nbsp; &nbsp;<br>&nbsp;&nbsp;&nbsp; 这里0x001为从0x000开始的inc DWORD PTR [???]的二进制编码中存储???的起始地址(这里假设inc的机器码的第2－5字节为要+1的绝对地址，需要知道确切情况可查手册)。这个表告诉链接器，在本编译单元0x001的位置上有一个地址，该地址值不明，但是具有符号n。<br>&nbsp;&nbsp;&nbsp; 链接的时候，链接器在2.o里发现了未解决符号n，那么在查找所有编译单元的时候，在1.o中发现了导出符号n，那么链接器就会将n的地址0x000填写到2.o的0x001的位置上。<br>&nbsp;&nbsp;&nbsp; &#8220;打住&#8221;，可能你就会跳出来指责我了。如果这样做得话，岂不是g的内容就会变成inc DWORD PTR [0x000]，按照之前的理解，这是将本单元的0x000地址的4字节加1，而不是将1.o的对应位置加1。是的，因为每个编译单元的地址都是从0开始的，所以最终拼接起来的时候地址会重复。所以链接器会在拼接的时候对各个单元的地址进行调整。这个例子中，假设2.o的0x00000000地址被定位在可执行文件的0x00001000上，而1.o的0x00000000地址被定位在可执行文件的0x00002000上，那么实际上对链接器来说，1.o的导出符号表其实<br>&nbsp;&nbsp; &nbsp;符号&nbsp;&nbsp; &nbsp;地址<br>&nbsp;&nbsp; &nbsp;n&nbsp;&nbsp; &nbsp;0x000 + 0x2000<br>&nbsp;&nbsp; &nbsp;_f&nbsp;&nbsp; &nbsp;0x004 + 0x2000<br>&nbsp;&nbsp;&nbsp; 而未解决符号表为空<br>&nbsp;&nbsp;&nbsp; 2.o的导出符号表为<br>&nbsp;&nbsp; &nbsp;符号&nbsp;&nbsp; &nbsp;地址<br>&nbsp;&nbsp; &nbsp;_g&nbsp;&nbsp; &nbsp;0x000 + 0x1000<br>&nbsp;&nbsp;&nbsp; 未解决符号表为<br>&nbsp;&nbsp; &nbsp;符号&nbsp;&nbsp; &nbsp;地址&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;<br>&nbsp;&nbsp; &nbsp;n&nbsp;&nbsp; &nbsp;0x001 + 0x1000<br>所以最终g的代码会变为inc DWORD PTR [0x000 + 0x2000]。<br>&nbsp;&nbsp;&nbsp; 最后还有一个漏洞，既然最后n的地址变为0x2000了，那么以前f的代码inc DWORD PTR [0x000]就是错误的了。所以目标文件为此还要提供一个表，叫做地址重定向表address redirect table。<br>&nbsp;&nbsp;&nbsp; 对于1.o来说，它的重定向表为<br>&nbsp;&nbsp; &nbsp;地址<br>&nbsp;&nbsp; &nbsp;0x005<br>&nbsp;&nbsp;&nbsp; 这个表不需要符号，当链接器处理这个表的时候，发现地址为0x005的位置上有一个地址需要重定向，那么直接在以0x005开始的4个字节上加上0x2000就可以了。<br>&nbsp;&nbsp;&nbsp; 让我们总结一下：编译器把一个cpp编译为目标文件的时候，除了要在目标文件里写入cpp里包含的数据和代码，还要至少提供3个表：未解决符号表，导出符号表和地址重定向表。<br>&nbsp;&nbsp;&nbsp; 未解决符号表提供了所有在该编译单元里引用但是定义并不在本编译单元里的符号及其出现的地址。<br>&nbsp;&nbsp;&nbsp; 导出符号表提供了本编译单元具有定义，并且愿意提供给其他编译单元使用的符号及其地址。<br>&nbsp;&nbsp;&nbsp; 地址重定向表提供了本编译单元所有对自身地址的引用的记录。<br>&nbsp;&nbsp;&nbsp; 链接器进行链接的时候，首先决定各个目标文件在最终可执行文件里的位置。然后访问所有目标文件的地址重定向表，对其中记录的地址进行重定向（即加上该编译单元实际在可执行文件里的起始地址）。然后遍历所有目标文件的未解决符号表，并且在所有的导出符号表里查找匹配的符号，并在未解决符号表中所记录的位置上填写实际的地址（也要加上拥有该符号定义的编译单元实际在可执行文件里的起始地址）。最后把所有的目标文件的内容写在各自的位置上，再作一些别的工作，一个可执行文件就出炉了。<br>&nbsp;&nbsp;&nbsp; 最终link 1.o 2.o .... 所生成的可执行文件大概是<br>&nbsp;&nbsp; &nbsp;0x00000000&nbsp; ????（别的一些信息）<br>&nbsp;&nbsp; &nbsp;....<br>&nbsp;&nbsp; &nbsp;0x00001000&nbsp; inc DWORD PTR [0x00002000]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;//这里是2.o的开始，也就是g的定义<br>&nbsp;&nbsp; &nbsp;0x00001005&nbsp; ret&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;//假设inc为5个字节，这里是g的结尾<br>&nbsp;&nbsp; &nbsp;....<br>&nbsp;&nbsp; &nbsp;0x00002000&nbsp; 0x00000001&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;//这里是1.o的开始，也是n的定义（初始化为1）<br>&nbsp;&nbsp; &nbsp;0x00002004&nbsp; inc DWORD PTR [0x00002000]&nbsp;&nbsp; &nbsp; &nbsp;&nbsp; &nbsp;//这里是f的开始<br>&nbsp;&nbsp; &nbsp;0x00002009&nbsp; ret&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;//假设inc为5个字节，这里是f的结尾<br>&nbsp;&nbsp; &nbsp;...<br>&nbsp;&nbsp; &nbsp;...<br>&nbsp;&nbsp;&nbsp; 实际链接的时候更为复杂，因为实际的目标文件里把数据／代码分为好几个区，重定向等要按区进行，但原理是一样的。<br><br><br>&nbsp;&nbsp; &nbsp;<br>&nbsp;&nbsp;&nbsp; 现在我们可以来看看几个经典的链接错误了：<br>&nbsp;&nbsp; &nbsp;unresolved external link..<br>&nbsp;&nbsp; &nbsp;这个很显然，是链接器发现一个未解决符号，但是在导出符号表里没有找到对应的項。<br>&nbsp;&nbsp; &nbsp;解决方案么，当然就是在某个编译单元里提供这个符号的定义就行了。（注意，这个符号可以是一个变量，也可以是一个函数），也可以看看是不是有什么该链接的文件没有链接<br>&nbsp;&nbsp; &nbsp;duplicated external simbols...<br>&nbsp;&nbsp; &nbsp;这个则是导出符号表里出现了重复项，因此链接器无法确定应该使用哪一个。这可能是使用了重复的名称，也可能有别的原因。<br><br><br>&nbsp;&nbsp;&nbsp; 我们再来看看C/C++语言里针对这一些而提供的特性：<br>&nbsp;&nbsp; &nbsp;extern:这是告诉编译器，这个符号在别的编译单元里定义，也就是要把这个符号放到未解决符号表里去。（外部链接）<br>&nbsp;&nbsp; &nbsp;<br>&nbsp;&nbsp; &nbsp;static:如果该关键字位于全局函数或者变量的声明的前面，表明该编译单元不导出这个函数／变量的符号。因此无法在别的编译单元里使用。（内部链接）。如果是static局部变量，则该变量的存储方式和全局变量一样，但是仍然不导出符号。<br>&nbsp;&nbsp; &nbsp;<br>&nbsp;&nbsp; &nbsp;默认链接属性：对于函数和变量，模认外部链接，对于const变量，默认内部链接。（可以通过添加extern和static改变链接属性）<br><br>&nbsp;&nbsp; &nbsp;外部链接的利弊：外部链接的符号，可以在整个程序范围内使用（因为导出了符号）。但是同时要求其他的编译单元不能导出相同的符号（不然就是duplicated external simbols)<br><br>&nbsp;&nbsp; &nbsp;内部链接的利弊：内部链接的符号，不能在别的编译单元内使用。但是不同的编译单元可以拥有同样名称的内部链接符号。<br><br>&nbsp;&nbsp; &nbsp;为什么头文件里一般只可以有声明不能有定义：头文件可以被多个编译单元包含，如果头文件里有定义，那么每个包含这个头文件的编译单元就都会对同一个符号进行定义，如果该符号为外部链接，则会导致duplicated external simbols。因此如果头文件里要定义，必须保证定义的符号只能具有内部链接。<br><br>&nbsp;&nbsp; &nbsp;为什么常量默认为内部链接，而变量不是：<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;这就是为了能够在头文件里如const int n = 0这样的定义常量。由于常量是只读的，因此即使每个编译单元都拥有一份定义也没有关系。如果一个定义于头文件里的变量拥有内部链接，那么如果出现多个编译单元都定义该变量，则其中一个编译单元对该变量进行修改，不会影响其他单元的同一变量，会产生意想不到的后果。<br><br>&nbsp;&nbsp; &nbsp;为什么函数默认是外部链接：<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;虽然函数是只读的，但是和变量不同，函数在代码编写的时候非常容易变化，如果函数默认具有内部链接，则人们会倾向于把函数定义在头文件里，那么一旦函数被修改，所有包含了该头文件的编译单元都要被重新编译。另外，函数里定义的静态局部变量也将被定义在头文件里。<br><br>&nbsp;&nbsp; &nbsp;为什么类的静态变量不可以就地初始化：所谓就地初始化就是类似于这样的情况：<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;class A<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;{<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;static char msg[] = "aha";<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;};<br>不允许这样做得原因是，由于class的声明通常是在头文件里，如果允许这样做，其实就相当于在头文件里定义了一个非const变量。<br><br>&nbsp;&nbsp; &nbsp;在C++里，头文件定义一个const对象会怎么样：<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;一般不会怎么样，这个和C里的在头文件里定义const int一样，每一个包含了这个头文件的编译单元都会定义这个对象。但由于该对象是const的，所以没什么影响。但是：有2种情况可能破坏这个局面：<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;1。如果涉及到对这个const对象取地址并且依赖于这个地址的唯一性，那么在不同的编译单元里，取到的地址可以不同。（但一般很少这么做）<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;2。如果这个对象具有mutable的变量，某个编译单元对其进行修改，则同样不会影响到别的编译单元。<br><br>&nbsp;&nbsp; &nbsp;为什么类的静态常量也不可以就地初始化：<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;因为这相当于在头文件里定义了const对象。作为例外，int/char等可以进行就地初始化，是因为这些变量可以直接被优化为立即数，就和宏一样。<br><br>&nbsp;&nbsp; &nbsp;内联函数：<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;C++里的内联函数由于类似于一个宏，因此不存在链接属性问题。<br><br>&nbsp;&nbsp; &nbsp;为什么公共使用的内联函数要定义于头文件里：<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;因为编译时编译单元之间互相不知道，如果内联函数被定义于.cpp文件中，编译其他使用该函数的编译单元的时候没有办法找到函数的定义，因此无法对函数进行展开。所以说如果内联函数定义于.cpp文件里，那么就只有这个cpp文件可以是用这个函数。<br><br>&nbsp;&nbsp; &nbsp;头文件里内联函数被拒绝会怎样：<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;如果定义于头文件里的内联函数被拒绝，那么编译器会自动在每个包含了该头文件的编译单元里定义这个函数并且不导出符号。<br><br>&nbsp;&nbsp; &nbsp;如果被拒绝的内联函数里定义了静态局部变量，这个变量会被定义于何处：<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;早期的编译器会在每个编译单元里定义一个，并因此产生错误的结果，较新的编译器会解决这个问题，手段未知。<br><br>&nbsp;&nbsp; &nbsp;为什么export关键字没人实现：<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;export要求编译器跨编译单元查找函数定义，使得编译器实现非常困难。<br><br><br><br><br>&nbsp; 编译和静态链接就分析到这里，我会带着动态链接和load的详解杀回来<br><br><br><br><br><br><br>
<img src ="http://www.cppblog.com/shifan3/aggbug/17325.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/shifan3/" target="_blank">shifan3</a> 2007-01-05 16:03 <a href="http://www.cppblog.com/shifan3/archive/2007/01/05/17325.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[yc]总结一下C++的名称查找顺序</title><link>http://www.cppblog.com/shifan3/archive/2006/12/27/16902.html</link><dc:creator>shifan3</dc:creator><author>shifan3</author><pubDate>Wed, 27 Dec 2006 03:04:00 GMT</pubDate><guid>http://www.cppblog.com/shifan3/archive/2006/12/27/16902.html</guid><wfw:comment>http://www.cppblog.com/shifan3/comments/16902.html</wfw:comment><comments>http://www.cppblog.com/shifan3/archive/2006/12/27/16902.html#Feedback</comments><slash:comments>8</slash:comments><wfw:commentRss>http://www.cppblog.com/shifan3/comments/commentRss/16902.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/shifan3/services/trackbacks/16902.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: &nbsp;1。符号查找（对于函数此时只看名字，不看参数）&nbsp;&nbsp;&nbsp; 大致顺序是&nbsp;&nbsp;&nbsp; (1)如果有限定名( XXX:: )那么就直接在XXX里查找&nbsp;&nbsp;&nbsp; (2)函数局部名字空间&nbsp;&nbsp;&nbsp; (3)(如果是成员)类名字空间&nbsp;&nbsp;&nbsp; (4)递归向上至所有基类的...&nbsp;&nbsp;<a href='http://www.cppblog.com/shifan3/archive/2006/12/27/16902.html'>阅读全文</a><img src ="http://www.cppblog.com/shifan3/aggbug/16902.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/shifan3/" target="_blank">shifan3</a> 2006-12-27 11:04 <a href="http://www.cppblog.com/shifan3/archive/2006/12/27/16902.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[yc]伪typeof</title><link>http://www.cppblog.com/shifan3/archive/2006/12/21/16690.html</link><dc:creator>shifan3</dc:creator><author>shifan3</author><pubDate>Thu, 21 Dec 2006 06:29:00 GMT</pubDate><guid>http://www.cppblog.com/shifan3/archive/2006/12/21/16690.html</guid><wfw:comment>http://www.cppblog.com/shifan3/comments/16690.html</wfw:comment><comments>http://www.cppblog.com/shifan3/archive/2006/12/21/16690.html#Feedback</comments><slash:comments>5</slash:comments><wfw:commentRss>http://www.cppblog.com/shifan3/comments/commentRss/16690.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/shifan3/services/trackbacks/16690.html</trackback:ping><description><![CDATA[<br><br>发信人: shifan (学习浮云技术), 板面: C++<br>标&nbsp; 题: 伪typeof<br>发信站: 飘渺水云间 (Tue Dec 19 16:38:45 2006), 转信<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"><span style="COLOR: #008080">&nbsp;1</span>&nbsp;<span style="COLOR: #008000">/*</span><span style="COLOR: #008000"><br></span><span style="COLOR: #008080">&nbsp;2</span>&nbsp;<span style="COLOR: #008000">用标准C++实现typeof是不可能的<br></span><span style="COLOR: #008080">&nbsp;3</span>&nbsp;<span style="COLOR: #008000">这个是我写的一个approached&nbsp;typeof<br></span><span style="COLOR: #008080">&nbsp;4</span>&nbsp;<span style="COLOR: #008000">所有需要被静态反射出来的类型必须先用DECL_TYPE注册<br></span><span style="COLOR: #008080">&nbsp;5</span>&nbsp;<span style="COLOR: #008000">模板如果仅仅带有1个参数可以用DECL_TEMPLATE_1注册<br></span><span style="COLOR: #008080">&nbsp;6</span>&nbsp;<span style="COLOR: #008000">多个参数的模板还不支持。。<br></span><span style="COLOR: #008080">&nbsp;7</span>&nbsp;<span style="COLOR: #008000">主要是没想好编码<br></span><span style="COLOR: #008080">&nbsp;8</span>&nbsp;<span style="COLOR: #008000"><br></span><span style="COLOR: #008080">&nbsp;9</span>&nbsp;<span style="COLOR: #008000">总共能注册64个类型<br></span><span style="COLOR: #008080">10</span>&nbsp;<span style="COLOR: #008000">可以通过MAX_TYPE_NUMBER设置<br></span><span style="COLOR: #008080">11</span>&nbsp;<span style="COLOR: #008000"><br></span><span style="COLOR: #008080">12</span>&nbsp;<span style="COLOR: #008000">支持的模板嵌套层数大约为32&nbsp;／&nbsp;log2(MAX_TYPE_NUMBER)<br></span><span style="COLOR: #008080">13</span>&nbsp;<span style="COLOR: #008000">MAX_TYPE_NUMBER必须为2的整次数幂<br></span><span style="COLOR: #008080">14</span>&nbsp;<span style="COLOR: #008000"></span><span style="COLOR: #008000">*/</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">15</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #0000ff">namespace</span><span style="COLOR: #000000">&nbsp;my_typeof<br></span><span style="COLOR: #008080">16</span>&nbsp;<span style="COLOR: #000000">{<br></span><span style="COLOR: #008080">17</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">18</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;</span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;MAX_TYPE_NUMBER&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">64</span><span style="COLOR: #000000">;<br></span><span style="COLOR: #008080">19</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">20</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;template&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;N</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">21</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;</span><span style="COLOR: #0000ff">struct</span><span style="COLOR: #000000">&nbsp;dummy<br></span><span style="COLOR: #008080">22</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;{<br></span><span style="COLOR: #008080">23</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;a[N];<br></span><span style="COLOR: #008080">24</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;};<br></span><span style="COLOR: #008080">25</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">26</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">27</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;template&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;N,&nbsp;typename&nbsp;Arg1</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">28</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;</span><span style="COLOR: #0000ff">struct</span><span style="COLOR: #000000">&nbsp;select_by_number_1;<br></span><span style="COLOR: #008080">29</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">30</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;template&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;N</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">31</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;</span><span style="COLOR: #0000ff">struct</span><span style="COLOR: #000000">&nbsp;select_by_number<br></span><span style="COLOR: #008080">32</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;{<br></span><span style="COLOR: #008080">33</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;typename&nbsp;select_by_number_1</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">N&nbsp;</span><span style="COLOR: #000000">%</span><span style="COLOR: #000000">&nbsp;MAX_TYPE_NUMBER,&nbsp;typename<br></span><span style="COLOR: #008080">34</span>&nbsp;<span style="COLOR: #000000">select_by_number</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">N&nbsp;</span><span style="COLOR: #000000">/</span><span style="COLOR: #000000">&nbsp;MAX_TYPE_NUMBER</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">::type</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">::type&nbsp;type;<br></span><span style="COLOR: #008080">35</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;};<br></span><span style="COLOR: #008080">36</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">37</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">38</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;template&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">typename&nbsp;T</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">39</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;</span><span style="COLOR: #0000ff">struct</span><span style="COLOR: #000000">&nbsp;number_of<br></span><span style="COLOR: #008080">40</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;{<br></span><span style="COLOR: #008080">41</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">static</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;v&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">sizeof</span><span style="COLOR: #000000">(generic_f(</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">(T</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">)</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">))&nbsp;</span><span style="COLOR: #000000">/</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">sizeof</span><span style="COLOR: #000000">(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">);<br></span><span style="COLOR: #008080">42</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;};<br></span><span style="COLOR: #008080">43</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">44</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">45</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #0000ff">#define</span><span style="COLOR: #000000">&nbsp;DECL_TYPE(T,&nbsp;N)&nbsp;\</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">46</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;</span><span style="COLOR: #0000ff">namespace</span><span style="COLOR: #000000">&nbsp;my_typeof{&nbsp;&nbsp;\<br></span><span style="COLOR: #008080">47</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;template</span><span style="COLOR: #000000">&lt;&gt;</span><span style="COLOR: #000000">\<br></span><span style="COLOR: #008080">48</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;</span><span style="COLOR: #0000ff">struct</span><span style="COLOR: #000000">&nbsp;select_by_number</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">N</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">&nbsp;\<br></span><span style="COLOR: #008080">49</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;{\<br></span><span style="COLOR: #008080">50</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;T&nbsp;type;\<br></span><span style="COLOR: #008080">51</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;};\<br></span><span style="COLOR: #008080">52</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;dummy&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">N</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">&nbsp;generic_f(</span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000">&nbsp;T</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">);}<br></span><span style="COLOR: #008080">53</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">54</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">55</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #0000ff">#define</span><span style="COLOR: #000000">&nbsp;DECL_TEMPLATE_1(T,&nbsp;N)&nbsp;\</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">56</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;</span><span style="COLOR: #0000ff">namespace</span><span style="COLOR: #000000">&nbsp;my_typeof{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\<br></span><span style="COLOR: #008080">57</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;template</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">typename&nbsp;Arg1</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">\<br></span><span style="COLOR: #008080">58</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;</span><span style="COLOR: #0000ff">struct</span><span style="COLOR: #000000">&nbsp;select_by_number_1</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">N,&nbsp;Arg1</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">\<br></span><span style="COLOR: #008080">59</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;{\<br></span><span style="COLOR: #008080">60</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;T</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">Arg1</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">&nbsp;type;\<br></span><span style="COLOR: #008080">61</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;};\<br></span><span style="COLOR: #008080">62</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;template&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">typename&nbsp;Arg1</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">\<br></span><span style="COLOR: #008080">63</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;dummy</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">N&nbsp;</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">&nbsp;number_of</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">Arg1</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">::v&nbsp;</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;MAX_TYPE_NUMBER&nbsp;</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">&nbsp;generic_f(</span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000">&nbsp;T</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">Arg1</span><span style="COLOR: #000000">&gt;&amp;</span><span style="COLOR: #000000">);}<br></span><span style="COLOR: #008080">64</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">65</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">66</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">67</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #0000ff">#define</span><span style="COLOR: #000000">&nbsp;TYPE_OF(x)&nbsp;my_typeof::select_by_number&lt;sizeof(my_typeof::generic_f(x))&nbsp;/</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">68</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #0000ff">sizeof</span><span style="COLOR: #000000">&nbsp;(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">)</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">::type<br></span><span style="COLOR: #008080">69</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">70</span>&nbsp;<span style="COLOR: #000000">}<br></span><span style="COLOR: #008080">71</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">72</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">73</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">sample</span><span style="COLOR: #008000"><br></span><span style="COLOR: #008080">74</span>&nbsp;<span style="COLOR: #008000"></span><span style="COLOR: #000000">#include&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">iostream</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">75</span>&nbsp;<span style="COLOR: #000000">#include&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">vector</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">76</span>&nbsp;<span style="COLOR: #000000">#include&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">list</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">77</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">78</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">79</span>&nbsp;<span style="COLOR: #000000">DECL_TYPE(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">);<br></span><span style="COLOR: #008080">80</span>&nbsp;<span style="COLOR: #000000">DECL_TEMPLATE_1(std::vector,&nbsp;</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">);<br></span><span style="COLOR: #008080">81</span>&nbsp;<span style="COLOR: #000000">DECL_TEMPLATE_1(std::list,&nbsp;</span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">);<br></span><span style="COLOR: #008080">82</span>&nbsp;<span style="COLOR: #000000">DECL_TYPE(</span><span style="COLOR: #0000ff">double</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">)<br></span><span style="COLOR: #008080">83</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">84</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #0000ff">using</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">namespace</span><span style="COLOR: #000000">&nbsp;std;<br></span><span style="COLOR: #008080">85</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;main(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">[])<br></span><span style="COLOR: #008080">86</span>&nbsp;<span style="COLOR: #000000">{<br></span><span style="COLOR: #008080">87</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;vector</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">list</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">vector</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">list</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #0000ff">double</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">&nbsp;v1;<br></span><span style="COLOR: #008080">88</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;TYPE_OF(v1)&nbsp;v2;<br></span><span style="COLOR: #008080">89</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;v1&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;v2;<br></span><span style="COLOR: #008080">90</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;<br></span><span style="COLOR: #008080">91</span>&nbsp;<span style="COLOR: #000000">}<br></span><span style="COLOR: #008080">92</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">93</span>&nbsp;<span style="COLOR: #000000"></span></div>
<br><br>--<br>You well 撒法！You well all 撒法！<br><br>※ 内容修改:&#183;shifan 于 Dec 21 14:21:57 修改本文内容&#183;[FROM: shifan]<br>※ 来源:&#183;飘渺水云间 freecity.cn&#183;[FROM: shifan]<br>
<img src ="http://www.cppblog.com/shifan3/aggbug/16690.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/shifan3/" target="_blank">shifan3</a> 2006-12-21 14:29 <a href="http://www.cppblog.com/shifan3/archive/2006/12/21/16690.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[yc]Multi Bit Mask</title><link>http://www.cppblog.com/shifan3/archive/2006/10/26/14264.html</link><dc:creator>shifan3</dc:creator><author>shifan3</author><pubDate>Thu, 26 Oct 2006 15:37:00 GMT</pubDate><guid>http://www.cppblog.com/shifan3/archive/2006/10/26/14264.html</guid><wfw:comment>http://www.cppblog.com/shifan3/comments/14264.html</wfw:comment><comments>http://www.cppblog.com/shifan3/archive/2006/10/26/14264.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.cppblog.com/shifan3/comments/commentRss/14264.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/shifan3/services/trackbacks/14264.html</trackback:ping><description><![CDATA[<p>boost的integer/integer_mask.hpp仅仅做了单个位的bit mask<br>要多个位必须写很多遍high_bit_mask_t<br>使用low_bits_mask_t也不能完全解决问题<br>所以自己用Typelist的那种写法写了一个</p>
<p>用法举例<br>bit_mask&lt;INT_LIST_2(2, 3)&gt;::value返回一个值，该值的第2、3位被置为1<br>其余位为0<br></p>
<p>&#160;</p>
<div style="BORDER-RIGHT: rgb(204,204,204) 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: rgb(204,204,204) 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: rgb(204,204,204) 1px solid; WIDTH: 98%; PADDING-TOP: 4px; BORDER-BOTTOM: rgb(204,204,204) 1px solid; BACKGROUND-COLOR: rgb(238,238,238)"><span style="COLOR: rgb(0,128,128)">&nbsp;&nbsp;1</span>&nbsp;<span style="COLOR: rgb(0,0,0)"><br></span><span style="COLOR: rgb(0,128,128)">&nbsp;&nbsp;2</span>&nbsp;<span style="COLOR: rgb(0,0,0)"></span><span style="COLOR: rgb(0,0,255)">namespace</span><span style="COLOR: rgb(0,0,0)">&nbsp;multi_bit_mask<br></span><span style="COLOR: rgb(0,128,128)">&nbsp;&nbsp;3</span>&nbsp;<span style="COLOR: rgb(0,0,0)">{<br></span><span style="COLOR: rgb(0,128,128)">&nbsp;&nbsp;4</span>&nbsp;<span style="COLOR: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: rgb(0,0,255)">namespace</span><span style="COLOR: rgb(0,0,0)">&nbsp;details<br></span><span style="COLOR: rgb(0,128,128)">&nbsp;&nbsp;5</span>&nbsp;<span style="COLOR: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;{<br></span><span style="COLOR: rgb(0,128,128)">&nbsp;&nbsp;6</span>&nbsp;<span style="COLOR: rgb(0,0,0)"><br></span><span style="COLOR: rgb(0,128,128)">&nbsp;&nbsp;7</span>&nbsp;<span style="COLOR: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;template&nbsp;</span><span style="COLOR: rgb(0,0,0)">&lt;</span><span style="COLOR: rgb(0,0,0)">typename&nbsp;T</span><span style="COLOR: rgb(0,0,0)">&gt;</span><span style="COLOR: rgb(0,0,0)"><br></span><span style="COLOR: rgb(0,128,128)">&nbsp;&nbsp;8</span>&nbsp;<span style="COLOR: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: rgb(0,0,255)">struct</span><span style="COLOR: rgb(0,0,0)">&nbsp;get_size<br></span><span style="COLOR: rgb(0,128,128)">&nbsp;&nbsp;9</span>&nbsp;<span style="COLOR: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br></span><span style="COLOR: rgb(0,128,128)">&nbsp;10</span>&nbsp;<span style="COLOR: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: rgb(0,0,255)">enum</span><span style="COLOR: rgb(0,0,0)">&nbsp;{size&nbsp;</span><span style="COLOR: rgb(0,0,0)">=</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,255)">sizeof</span><span style="COLOR: rgb(0,0,0)">(T)};&nbsp;<br></span><span style="COLOR: rgb(0,128,128)">&nbsp;11</span>&nbsp;<span style="COLOR: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;};<br></span><span style="COLOR: rgb(0,128,128)">&nbsp;12</span>&nbsp;<span style="COLOR: rgb(0,0,0)"><br></span><span style="COLOR: rgb(0,128,128)">&nbsp;13</span>&nbsp;<span style="COLOR: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;template&nbsp;</span><span style="COLOR: rgb(0,0,0)">&lt;</span><span style="COLOR: rgb(0,0,255)">int</span><span style="COLOR: rgb(0,0,0)">&nbsp;Bit</span><span style="COLOR: rgb(0,0,0)">&gt;</span><span style="COLOR: rgb(0,0,0)"><br></span><span style="COLOR: rgb(0,128,128)">&nbsp;14</span>&nbsp;<span style="COLOR: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: rgb(0,0,255)">struct</span><span style="COLOR: rgb(0,0,0)">&nbsp;bit_storage<br></span><span style="COLOR: rgb(0,128,128)">&nbsp;15</span>&nbsp;<span style="COLOR: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br></span><span style="COLOR: rgb(0,128,128)">&nbsp;16</span>&nbsp;<span style="COLOR: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;typename&nbsp;bit_storage</span><span style="COLOR: rgb(0,0,0)">&lt;</span><span style="COLOR: rgb(0,0,0)">Bit&nbsp;</span><span style="COLOR: rgb(0,0,0)">-</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">1</span><span style="COLOR: rgb(0,0,0)">&gt;</span><span style="COLOR: rgb(0,0,0)">::storage_type&nbsp;storage_type;<br></span><span style="COLOR: rgb(0,128,128)">&nbsp;17</span>&nbsp;<span style="COLOR: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;};<br></span><span style="COLOR: rgb(0,128,128)">&nbsp;18</span>&nbsp;<span style="COLOR: rgb(0,0,0)"><br></span><span style="COLOR: rgb(0,128,128)">&nbsp;19</span>&nbsp;<span style="COLOR: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: rgb(0,128,0)">//</span><span style="COLOR: rgb(0,128,0)">---------platform&nbsp;dependency-----------------------</span><span style="COLOR: rgb(0,128,0)"><br></span><span style="COLOR: rgb(0,128,128)">&nbsp;20</span>&nbsp;<span style="COLOR: rgb(0,128,0)"></span><span style="COLOR: rgb(0,0,0)"><br></span><span style="COLOR: rgb(0,128,128)">&nbsp;21</span>&nbsp;<span style="COLOR: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;unsigned&nbsp;</span><span style="COLOR: rgb(0,0,255)">int</span><span style="COLOR: rgb(0,0,0)">&nbsp;smallest_storage_type;<br></span><span style="COLOR: rgb(0,128,128)">&nbsp;22</span>&nbsp;<span style="COLOR: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;unsigned&nbsp;</span><span style="COLOR: rgb(0,0,255)">long</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,255)">long</span><span style="COLOR: rgb(0,0,0)">&nbsp;largest_storage_type;<br></span><span style="COLOR: rgb(0,128,128)">&nbsp;23</span>&nbsp;<span style="COLOR: rgb(0,0,0)"><br></span><span style="COLOR: rgb(0,128,128)">&nbsp;24</span>&nbsp;<span style="COLOR: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br></span><span style="COLOR: rgb(0,128,128)">&nbsp;25</span>&nbsp;<span style="COLOR: rgb(0,0,0)"><br></span><span style="COLOR: rgb(0,128,128)">&nbsp;26</span>&nbsp;<span style="COLOR: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;template&nbsp;</span><span style="COLOR: rgb(0,0,0)">&lt;&gt;</span><span style="COLOR: rgb(0,0,0)"><br></span><span style="COLOR: rgb(0,128,128)">&nbsp;27</span>&nbsp;<span style="COLOR: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: rgb(0,0,255)">struct</span><span style="COLOR: rgb(0,0,0)">&nbsp;bit_storage</span><span style="COLOR: rgb(0,0,0)">&lt;</span><span style="COLOR: rgb(0,0,0)">0</span><span style="COLOR: rgb(0,0,0)">&gt;</span><span style="COLOR: rgb(0,0,0)"><br></span><span style="COLOR: rgb(0,128,128)">&nbsp;28</span>&nbsp;<span style="COLOR: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br></span><span style="COLOR: rgb(0,128,128)">&nbsp;29</span>&nbsp;<span style="COLOR: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;smallest_storage_type&nbsp;storage_type;<br></span><span style="COLOR: rgb(0,128,128)">&nbsp;30</span>&nbsp;<span style="COLOR: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;};<br></span><span style="COLOR: rgb(0,128,128)">&nbsp;31</span>&nbsp;<span style="COLOR: rgb(0,0,0)"><br></span><span style="COLOR: rgb(0,128,128)">&nbsp;32</span>&nbsp;<span style="COLOR: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;template&nbsp;</span><span style="COLOR: rgb(0,0,0)">&lt;&gt;</span><span style="COLOR: rgb(0,0,0)"><br></span><span style="COLOR: rgb(0,128,128)">&nbsp;33</span>&nbsp;<span style="COLOR: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: rgb(0,0,255)">struct</span><span style="COLOR: rgb(0,0,0)">&nbsp;bit_storage</span><span style="COLOR: rgb(0,0,0)">&lt;</span><span style="COLOR: rgb(0,0,0)">get_size</span><span style="COLOR: rgb(0,0,0)">&lt;</span><span style="COLOR: rgb(0,0,0)">smallest_storage_type</span><span style="COLOR: rgb(0,0,0)">&gt;</span><span style="COLOR: rgb(0,0,0)">::size&nbsp;</span><span style="COLOR: rgb(0,0,0)">*</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">8</span><span style="COLOR: rgb(0,0,0)">&gt;</span><span style="COLOR: rgb(0,0,0)"><br></span><span style="COLOR: rgb(0,128,128)">&nbsp;34</span>&nbsp;<span style="COLOR: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br></span><span style="COLOR: rgb(0,128,128)">&nbsp;35</span>&nbsp;<span style="COLOR: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;largest_storage_type&nbsp;storage_type;<br></span><span style="COLOR: rgb(0,128,128)">&nbsp;36</span>&nbsp;<span style="COLOR: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;};<br></span><span style="COLOR: rgb(0,128,128)">&nbsp;37</span>&nbsp;<span style="COLOR: rgb(0,0,0)"><br></span><span style="COLOR: rgb(0,128,128)">&nbsp;38</span>&nbsp;<span style="COLOR: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: rgb(0,128,0)">//</span><span style="COLOR: rgb(0,128,0)">disable&nbsp;the&nbsp;65th&nbsp;bit</span><span style="COLOR: rgb(0,128,0)"><br></span><span style="COLOR: rgb(0,128,128)">&nbsp;39</span>&nbsp;<span style="COLOR: rgb(0,128,0)"></span><span style="COLOR: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;template&nbsp;</span><span style="COLOR: rgb(0,0,0)">&lt;&gt;</span><span style="COLOR: rgb(0,0,0)"><br></span><span style="COLOR: rgb(0,128,128)">&nbsp;40</span>&nbsp;<span style="COLOR: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: rgb(0,0,255)">struct</span><span style="COLOR: rgb(0,0,0)">&nbsp;bit_storage</span><span style="COLOR: rgb(0,0,0)">&lt;</span><span style="COLOR: rgb(0,0,0)">get_size</span><span style="COLOR: rgb(0,0,0)">&lt;</span><span style="COLOR: rgb(0,0,0)">largest_storage_type</span><span style="COLOR: rgb(0,0,0)">&gt;</span><span style="COLOR: rgb(0,0,0)">::size&nbsp;</span><span style="COLOR: rgb(0,0,0)">*</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">8</span><span style="COLOR: rgb(0,0,0)">&gt;</span><span style="COLOR: rgb(0,0,0)"><br></span><span style="COLOR: rgb(0,128,128)">&nbsp;41</span>&nbsp;<span style="COLOR: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br></span><span style="COLOR: rgb(0,128,128)">&nbsp;42</span>&nbsp;<span style="COLOR: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;</span><span style="COLOR: rgb(0,0,255)">void</span><span style="COLOR: rgb(0,0,0)">&nbsp;storage_type;<br></span><span style="COLOR: rgb(0,128,128)">&nbsp;43</span>&nbsp;<span style="COLOR: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;};<br></span><span style="COLOR: rgb(0,128,128)">&nbsp;44</span>&nbsp;<span style="COLOR: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br></span><span style="COLOR: rgb(0,128,128)">&nbsp;45</span>&nbsp;<span style="COLOR: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: rgb(0,128,0)">//</span><span style="COLOR: rgb(0,128,0)">---------end&nbsp;of&nbsp;platform&nbsp;dependency----------------</span><span style="COLOR: rgb(0,128,0)"><br></span><span style="COLOR: rgb(0,128,128)">&nbsp;46</span>&nbsp;<span style="COLOR: rgb(0,128,0)"></span><span style="COLOR: rgb(0,0,0)"><br></span><span style="COLOR: rgb(0,128,128)">&nbsp;47</span>&nbsp;<span style="COLOR: rgb(0,0,0)"><br></span><span style="COLOR: rgb(0,128,128)">&nbsp;48</span>&nbsp;<span style="COLOR: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;template&nbsp;</span><span style="COLOR: rgb(0,0,0)">&lt;</span><span style="COLOR: rgb(0,0,0)">unsigned&nbsp;</span><span style="COLOR: rgb(0,0,255)">int</span><span style="COLOR: rgb(0,0,0)">&nbsp;N,&nbsp;typename&nbsp;Next</span><span style="COLOR: rgb(0,0,0)">&gt;</span><span style="COLOR: rgb(0,0,0)"><br></span><span style="COLOR: rgb(0,128,128)">&nbsp;49</span>&nbsp;<span style="COLOR: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: rgb(0,0,255)">struct</span><span style="COLOR: rgb(0,0,0)">&nbsp;int_list<br></span><span style="COLOR: rgb(0,128,128)">&nbsp;50</span>&nbsp;<span style="COLOR: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br></span><span style="COLOR: rgb(0,128,128)">&nbsp;51</span>&nbsp;<span style="COLOR: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;typename&nbsp;bit_storage</span><span style="COLOR: rgb(0,0,0)">&lt;</span><span style="COLOR: rgb(0,0,0)">N</span><span style="COLOR: rgb(0,0,0)">&gt;</span><span style="COLOR: rgb(0,0,0)">::storage_type&nbsp;storage_type;<br></span><span style="COLOR: rgb(0,128,128)">&nbsp;52</span>&nbsp;<span style="COLOR: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: rgb(0,0,255)">static</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,255)">const</span><span style="COLOR: rgb(0,0,0)">&nbsp;storage_type&nbsp;value&nbsp;</span><span style="COLOR: rgb(0,0,0)">=</span><span style="COLOR: rgb(0,0,0)">&nbsp;N;<br></span><span style="COLOR: rgb(0,128,128)">&nbsp;53</span>&nbsp;<span style="COLOR: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;Next&nbsp;next;<br></span><span style="COLOR: rgb(0,128,128)">&nbsp;54</span>&nbsp;<span style="COLOR: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;};<br></span><span style="COLOR: rgb(0,128,128)">&nbsp;55</span>&nbsp;<span style="COLOR: rgb(0,0,0)"><br></span><span style="COLOR: rgb(0,128,128)">&nbsp;56</span>&nbsp;<span style="COLOR: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: rgb(0,0,255)">struct</span><span style="COLOR: rgb(0,0,0)">&nbsp;null_type{};<br></span><span style="COLOR: rgb(0,128,128)">&nbsp;57</span>&nbsp;<span style="COLOR: rgb(0,0,0)"><br></span><span style="COLOR: rgb(0,128,128)">&nbsp;58</span>&nbsp;<span style="COLOR: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;template</span><span style="COLOR: rgb(0,0,0)">&lt;</span><span style="COLOR: rgb(0,0,0)">typename&nbsp;T1,&nbsp;typename&nbsp;T2,&nbsp;</span><span style="COLOR: rgb(0,0,255)">bool</span><span style="COLOR: rgb(0,0,0)">&nbsp;is_first</span><span style="COLOR: rgb(0,0,0)">&gt;</span><span style="COLOR: rgb(0,0,0)"><br></span><span style="COLOR: rgb(0,128,128)">&nbsp;59</span>&nbsp;<span style="COLOR: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: rgb(0,0,255)">struct</span><span style="COLOR: rgb(0,0,0)">&nbsp;selector<br></span><span style="COLOR: rgb(0,128,128)">&nbsp;60</span>&nbsp;<span style="COLOR: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br></span><span style="COLOR: rgb(0,128,128)">&nbsp;61</span>&nbsp;<span style="COLOR: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;T1&nbsp;type;<br></span><span style="COLOR: rgb(0,128,128)">&nbsp;62</span>&nbsp;<span style="COLOR: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;};<br></span><span style="COLOR: rgb(0,128,128)">&nbsp;63</span>&nbsp;<span style="COLOR: rgb(0,0,0)"><br></span><span style="COLOR: rgb(0,128,128)">&nbsp;64</span>&nbsp;<span style="COLOR: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;template</span><span style="COLOR: rgb(0,0,0)">&lt;</span><span style="COLOR: rgb(0,0,0)">typename&nbsp;T1,&nbsp;typename&nbsp;T2</span><span style="COLOR: rgb(0,0,0)">&gt;</span><span style="COLOR: rgb(0,0,0)"><br></span><span style="COLOR: rgb(0,128,128)">&nbsp;65</span>&nbsp;<span style="COLOR: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: rgb(0,0,255)">struct</span><span style="COLOR: rgb(0,0,0)">&nbsp;compare_type<br></span><span style="COLOR: rgb(0,128,128)">&nbsp;66</span>&nbsp;<span style="COLOR: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br></span><span style="COLOR: rgb(0,128,128)">&nbsp;67</span>&nbsp;<span style="COLOR: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: rgb(0,0,255)">const</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,255)">static</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,255)">bool</span><span style="COLOR: rgb(0,0,0)">&nbsp;is_larger&nbsp;</span><span style="COLOR: rgb(0,0,0)">=</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,255)">sizeof</span><span style="COLOR: rgb(0,0,0)">(T1)&nbsp;</span><span style="COLOR: rgb(0,0,0)">&gt;</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,255)">sizeof</span><span style="COLOR: rgb(0,0,0)">(T2);<br></span><span style="COLOR: rgb(0,128,128)">&nbsp;68</span>&nbsp;<span style="COLOR: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;typename&nbsp;selector</span><span style="COLOR: rgb(0,0,0)">&lt;</span><span style="COLOR: rgb(0,0,0)">T1,&nbsp;T2,&nbsp;is_larger</span><span style="COLOR: rgb(0,0,0)">&gt;</span><span style="COLOR: rgb(0,0,0)">::type&nbsp;large_type;<br></span><span style="COLOR: rgb(0,128,128)">&nbsp;69</span>&nbsp;<span style="COLOR: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;typename&nbsp;selector</span><span style="COLOR: rgb(0,0,0)">&lt;</span><span style="COLOR: rgb(0,0,0)">T1,&nbsp;T2,&nbsp;</span><span style="COLOR: rgb(0,0,0)">!</span><span style="COLOR: rgb(0,0,0)">is_larger</span><span style="COLOR: rgb(0,0,0)">&gt;</span><span style="COLOR: rgb(0,0,0)">::type&nbsp;small_type;<br></span><span style="COLOR: rgb(0,128,128)">&nbsp;70</span>&nbsp;<span style="COLOR: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;};<br></span><span style="COLOR: rgb(0,128,128)">&nbsp;71</span>&nbsp;<span style="COLOR: rgb(0,0,0)"><br></span><span style="COLOR: rgb(0,128,128)">&nbsp;72</span>&nbsp;<span style="COLOR: rgb(0,0,0)"><br></span><span style="COLOR: rgb(0,128,128)">&nbsp;73</span>&nbsp;<span style="COLOR: rgb(0,0,0)"><br></span><span style="COLOR: rgb(0,128,128)">&nbsp;74</span>&nbsp;<span style="COLOR: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;template</span><span style="COLOR: rgb(0,0,0)">&lt;</span><span style="COLOR: rgb(0,0,0)">typename&nbsp;T1,&nbsp;typename&nbsp;T2</span><span style="COLOR: rgb(0,0,0)">&gt;</span><span style="COLOR: rgb(0,0,0)"><br></span><span style="COLOR: rgb(0,128,128)">&nbsp;75</span>&nbsp;<span style="COLOR: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: rgb(0,0,255)">struct</span><span style="COLOR: rgb(0,0,0)">&nbsp;selector</span><span style="COLOR: rgb(0,0,0)">&lt;</span><span style="COLOR: rgb(0,0,0)">T1,&nbsp;T2,&nbsp;</span><span style="COLOR: rgb(0,0,255)">false</span><span style="COLOR: rgb(0,0,0)">&gt;</span><span style="COLOR: rgb(0,0,0)"><br></span><span style="COLOR: rgb(0,128,128)">&nbsp;76</span>&nbsp;<span style="COLOR: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br></span><span style="COLOR: rgb(0,128,128)">&nbsp;77</span>&nbsp;<span style="COLOR: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;T2&nbsp;type;<br></span><span style="COLOR: rgb(0,128,128)">&nbsp;78</span>&nbsp;<span style="COLOR: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;};<br></span><span style="COLOR: rgb(0,128,128)">&nbsp;79</span>&nbsp;<span style="COLOR: rgb(0,0,0)"><br></span><span style="COLOR: rgb(0,128,128)">&nbsp;80</span>&nbsp;<span style="COLOR: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;template&nbsp;</span><span style="COLOR: rgb(0,0,0)">&lt;</span><span style="COLOR: rgb(0,0,0)">typename&nbsp;List</span><span style="COLOR: rgb(0,0,0)">&gt;</span><span style="COLOR: rgb(0,0,0)"><br></span><span style="COLOR: rgb(0,128,128)">&nbsp;81</span>&nbsp;<span style="COLOR: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: rgb(0,0,255)">class</span><span style="COLOR: rgb(0,0,0)">&nbsp;find_largest_storage<br></span><span style="COLOR: rgb(0,128,128)">&nbsp;82</span>&nbsp;<span style="COLOR: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br></span><span style="COLOR: rgb(0,128,128)">&nbsp;83</span>&nbsp;<span style="COLOR: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;typename&nbsp;find_largest_storage</span><span style="COLOR: rgb(0,0,0)">&lt;</span><span style="COLOR: rgb(0,0,0)">typename&nbsp;List::next</span><span style="COLOR: rgb(0,0,0)">&gt;</span><span style="COLOR: rgb(0,0,0)">::storage_type&nbsp;T1;<br></span><span style="COLOR: rgb(0,128,128)">&nbsp;84</span>&nbsp;<span style="COLOR: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;typename&nbsp;bit_storage</span><span style="COLOR: rgb(0,0,0)">&lt;</span><span style="COLOR: rgb(0,0,0)">List::value</span><span style="COLOR: rgb(0,0,0)">&gt;</span><span style="COLOR: rgb(0,0,0)">::storage_type&nbsp;T2;<br></span><span style="COLOR: rgb(0,128,128)">&nbsp;85</span>&nbsp;<span style="COLOR: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: rgb(0,0,255)">public</span><span style="COLOR: rgb(0,0,0)">:<br></span><span style="COLOR: rgb(0,128,128)">&nbsp;86</span>&nbsp;<span style="COLOR: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;typename&nbsp;compare_type</span><span style="COLOR: rgb(0,0,0)">&lt;</span><span style="COLOR: rgb(0,0,0)">T1,&nbsp;T2</span><span style="COLOR: rgb(0,0,0)">&gt;</span><span style="COLOR: rgb(0,0,0)">::large_type&nbsp;storage_type;<br></span><span style="COLOR: rgb(0,128,128)">&nbsp;87</span>&nbsp;<span style="COLOR: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;};<br></span><span style="COLOR: rgb(0,128,128)">&nbsp;88</span>&nbsp;<span style="COLOR: rgb(0,0,0)"><br></span><span style="COLOR: rgb(0,128,128)">&nbsp;89</span>&nbsp;<span style="COLOR: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;template&nbsp;</span><span style="COLOR: rgb(0,0,0)">&lt;&gt;</span><span style="COLOR: rgb(0,0,0)"><br></span><span style="COLOR: rgb(0,128,128)">&nbsp;90</span>&nbsp;<span style="COLOR: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: rgb(0,0,255)">class</span><span style="COLOR: rgb(0,0,0)">&nbsp;find_largest_storage</span><span style="COLOR: rgb(0,0,0)">&lt;</span><span style="COLOR: rgb(0,0,0)">null_type</span><span style="COLOR: rgb(0,0,0)">&gt;</span><span style="COLOR: rgb(0,0,0)"><br></span><span style="COLOR: rgb(0,128,128)">&nbsp;91</span>&nbsp;<span style="COLOR: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br></span><span style="COLOR: rgb(0,128,128)">&nbsp;92</span>&nbsp;<span style="COLOR: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: rgb(0,0,255)">public</span><span style="COLOR: rgb(0,0,0)">:<br></span><span style="COLOR: rgb(0,128,128)">&nbsp;93</span>&nbsp;<span style="COLOR: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;smallest_storage_type&nbsp;storage_type;<br></span><span style="COLOR: rgb(0,128,128)">&nbsp;94</span>&nbsp;<span style="COLOR: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;};&nbsp;&nbsp;&nbsp;&nbsp;<br></span><span style="COLOR: rgb(0,128,128)">&nbsp;95</span>&nbsp;<span style="COLOR: rgb(0,0,0)"><br></span><span style="COLOR: rgb(0,128,128)">&nbsp;96</span>&nbsp;<span style="COLOR: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br></span><span style="COLOR: rgb(0,128,128)">&nbsp;97</span>&nbsp;<span style="COLOR: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;}<br></span><span style="COLOR: rgb(0,128,128)">&nbsp;98</span>&nbsp;<span style="COLOR: rgb(0,0,0)"><br></span><span style="COLOR: rgb(0,128,128)">&nbsp;99</span>&nbsp;<span style="COLOR: rgb(0,0,0)"><br></span><span style="COLOR: rgb(0,128,128)">100</span>&nbsp;<span style="COLOR: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br></span><span style="COLOR: rgb(0,128,128)">101</span>&nbsp;<span style="COLOR: rgb(0,0,0)"><br></span><span style="COLOR: rgb(0,128,128)">102</span>&nbsp;<span style="COLOR: rgb(0,0,0)"><br></span><span style="COLOR: rgb(0,128,128)">103</span>&nbsp;<span style="COLOR: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;template&nbsp;</span><span style="COLOR: rgb(0,0,0)">&lt;</span><span style="COLOR: rgb(0,0,255)">int</span><span style="COLOR: rgb(0,0,0)">&nbsp;N</span><span style="COLOR: rgb(0,0,0)">&gt;</span><span style="COLOR: rgb(0,0,0)"><br></span><span style="COLOR: rgb(0,128,128)">104</span>&nbsp;<span style="COLOR: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: rgb(0,0,255)">struct</span><span style="COLOR: rgb(0,0,0)">&nbsp;single_bit_mask<br></span><span style="COLOR: rgb(0,128,128)">105</span>&nbsp;<span style="COLOR: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;{<br></span><span style="COLOR: rgb(0,128,128)">106</span>&nbsp;<span style="COLOR: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;typename&nbsp;details::bit_storage</span><span style="COLOR: rgb(0,0,0)">&lt;</span><span style="COLOR: rgb(0,0,0)">N</span><span style="COLOR: rgb(0,0,0)">&gt;</span><span style="COLOR: rgb(0,0,0)">::storage_type&nbsp;storage_type;<br></span><span style="COLOR: rgb(0,128,128)">107</span>&nbsp;<span style="COLOR: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: rgb(0,0,255)">static</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,255)">const</span><span style="COLOR: rgb(0,0,0)">&nbsp;storage_type&nbsp;value&nbsp;<br></span><span style="COLOR: rgb(0,128,128)">108</span>&nbsp;<span style="COLOR: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: rgb(0,0,0)">=</span><span style="COLOR: rgb(0,0,0)">&nbsp;static_cast</span><span style="COLOR: rgb(0,0,0)">&lt;</span><span style="COLOR: rgb(0,0,0)">storage_type</span><span style="COLOR: rgb(0,0,0)">&gt;</span><span style="COLOR: rgb(0,0,0)">(single_bit_mask</span><span style="COLOR: rgb(0,0,0)">&lt;</span><span style="COLOR: rgb(0,0,0)">N&nbsp;</span><span style="COLOR: rgb(0,0,0)">-</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">1</span><span style="COLOR: rgb(0,0,0)">&gt;</span><span style="COLOR: rgb(0,0,0)">::value)&nbsp;</span><span style="COLOR: rgb(0,0,0)">*</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">2</span><span style="COLOR: rgb(0,0,0)">;<br></span><span style="COLOR: rgb(0,128,128)">109</span>&nbsp;<span style="COLOR: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;};<br></span><span style="COLOR: rgb(0,128,128)">110</span>&nbsp;<span style="COLOR: rgb(0,0,0)"><br></span><span style="COLOR: rgb(0,128,128)">111</span>&nbsp;<span style="COLOR: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;template&nbsp;</span><span style="COLOR: rgb(0,0,0)">&lt;&gt;</span><span style="COLOR: rgb(0,0,0)"><br></span><span style="COLOR: rgb(0,128,128)">112</span>&nbsp;<span style="COLOR: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: rgb(0,0,255)">struct</span><span style="COLOR: rgb(0,0,0)">&nbsp;single_bit_mask</span><span style="COLOR: rgb(0,0,0)">&lt;</span><span style="COLOR: rgb(0,0,0)">0</span><span style="COLOR: rgb(0,0,0)">&gt;</span><span style="COLOR: rgb(0,0,0)"><br></span><span style="COLOR: rgb(0,128,128)">113</span>&nbsp;<span style="COLOR: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;{<br></span><span style="COLOR: rgb(0,128,128)">114</span>&nbsp;<span style="COLOR: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;details::bit_storage</span><span style="COLOR: rgb(0,0,0)">&lt;</span><span style="COLOR: rgb(0,0,0)">0</span><span style="COLOR: rgb(0,0,0)">&gt;</span><span style="COLOR: rgb(0,0,0)">::storage_type&nbsp;storage_type;<br></span><span style="COLOR: rgb(0,128,128)">115</span>&nbsp;<span style="COLOR: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: rgb(0,0,255)">static</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,255)">const</span><span style="COLOR: rgb(0,0,0)">&nbsp;storage_type&nbsp;value&nbsp;</span><span style="COLOR: rgb(0,0,0)">=</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">1</span><span style="COLOR: rgb(0,0,0)">;<br></span><span style="COLOR: rgb(0,128,128)">116</span>&nbsp;<span style="COLOR: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;};<br></span><span style="COLOR: rgb(0,128,128)">117</span>&nbsp;<span style="COLOR: rgb(0,0,0)"><br></span><span style="COLOR: rgb(0,128,128)">118</span>&nbsp;<span style="COLOR: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;<br></span><span style="COLOR: rgb(0,128,128)">119</span>&nbsp;<span style="COLOR: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;details::null_type&nbsp;null_type;<br></span><span style="COLOR: rgb(0,128,128)">120</span>&nbsp;<span style="COLOR: rgb(0,0,0)"><br></span><span style="COLOR: rgb(0,128,128)">121</span>&nbsp;<span style="COLOR: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;template&nbsp;</span><span style="COLOR: rgb(0,0,0)">&lt;</span><span style="COLOR: rgb(0,0,255)">int</span><span style="COLOR: rgb(0,0,0)">&nbsp;N,&nbsp;typename&nbsp;Next</span><span style="COLOR: rgb(0,0,0)">&gt;</span><span style="COLOR: rgb(0,0,0)"><br></span><span style="COLOR: rgb(0,128,128)">122</span>&nbsp;<span style="COLOR: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: rgb(0,0,255)">struct</span><span style="COLOR: rgb(0,0,0)">&nbsp;int_list_t&nbsp;:&nbsp;</span><span style="COLOR: rgb(0,0,255)">public</span><span style="COLOR: rgb(0,0,0)">&nbsp;details::int_list</span><span style="COLOR: rgb(0,0,0)">&lt;</span><span style="COLOR: rgb(0,0,0)">N,&nbsp;Next</span><span style="COLOR: rgb(0,0,0)">&gt;</span><span style="COLOR: rgb(0,0,0)">&nbsp;{};<br></span><span style="COLOR: rgb(0,128,128)">123</span>&nbsp;<span style="COLOR: rgb(0,0,0)"><br></span><span style="COLOR: rgb(0,128,128)">124</span>&nbsp;<span style="COLOR: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;template&nbsp;</span><span style="COLOR: rgb(0,0,0)">&lt;</span><span style="COLOR: rgb(0,0,0)">typename&nbsp;List</span><span style="COLOR: rgb(0,0,0)">&gt;</span><span style="COLOR: rgb(0,0,0)"><br></span><span style="COLOR: rgb(0,128,128)">125</span>&nbsp;<span style="COLOR: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: rgb(0,0,255)">struct</span><span style="COLOR: rgb(0,0,0)">&nbsp;bit_mask<br></span><span style="COLOR: rgb(0,128,128)">126</span>&nbsp;<span style="COLOR: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;{<br></span><span style="COLOR: rgb(0,128,128)">127</span>&nbsp;<span style="COLOR: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: rgb(0,0,255)">public</span><span style="COLOR: rgb(0,0,0)">:<br></span><span style="COLOR: rgb(0,128,128)">128</span>&nbsp;<span style="COLOR: rgb(0,0,0)"><br></span><span style="COLOR: rgb(0,128,128)">129</span>&nbsp;<span style="COLOR: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;typename&nbsp;details::find_largest_storage</span><span style="COLOR: rgb(0,0,0)">&lt;</span><span style="COLOR: rgb(0,0,0)">List</span><span style="COLOR: rgb(0,0,0)">&gt;</span><span style="COLOR: rgb(0,0,0)">::storage_type&nbsp;storage_type;<br></span><span style="COLOR: rgb(0,128,128)">130</span>&nbsp;<span style="COLOR: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;<br></span><span style="COLOR: rgb(0,128,128)">131</span>&nbsp;<span style="COLOR: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: rgb(0,0,255)">static</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,255)">const</span><span style="COLOR: rgb(0,0,0)">&nbsp;storage_type&nbsp;value&nbsp;<br></span><span style="COLOR: rgb(0,128,128)">132</span>&nbsp;<span style="COLOR: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: rgb(0,0,0)">=</span><span style="COLOR: rgb(0,0,0)">&nbsp;static_cast</span><span style="COLOR: rgb(0,0,0)">&lt;</span><span style="COLOR: rgb(0,0,0)">storage_type</span><span style="COLOR: rgb(0,0,0)">&gt;</span><span style="COLOR: rgb(0,0,0)">(single_bit_mask</span><span style="COLOR: rgb(0,0,0)">&lt;</span><span style="COLOR: rgb(0,0,0)">List::value</span><span style="COLOR: rgb(0,0,0)">&gt;</span><span style="COLOR: rgb(0,0,0)">::value)&nbsp;<br></span><span style="COLOR: rgb(0,128,128)">133</span>&nbsp;<span style="COLOR: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: rgb(0,0,0)">|</span><span style="COLOR: rgb(0,0,0)">&nbsp;static_cast</span><span style="COLOR: rgb(0,0,0)">&lt;</span><span style="COLOR: rgb(0,0,0)">storage_type</span><span style="COLOR: rgb(0,0,0)">&gt;</span><span style="COLOR: rgb(0,0,0)">(bit_mask</span><span style="COLOR: rgb(0,0,0)">&lt;</span><span style="COLOR: rgb(0,0,0)">typename&nbsp;List::next</span><span style="COLOR: rgb(0,0,0)">&gt;</span><span style="COLOR: rgb(0,0,0)">::value);<br></span><span style="COLOR: rgb(0,128,128)">134</span>&nbsp;<span style="COLOR: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;};<br></span><span style="COLOR: rgb(0,128,128)">135</span>&nbsp;<span style="COLOR: rgb(0,0,0)"><br></span><span style="COLOR: rgb(0,128,128)">136</span>&nbsp;<span style="COLOR: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;template&nbsp;</span><span style="COLOR: rgb(0,0,0)">&lt;&gt;</span><span style="COLOR: rgb(0,0,0)"><br></span><span style="COLOR: rgb(0,128,128)">137</span>&nbsp;<span style="COLOR: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: rgb(0,0,255)">struct</span><span style="COLOR: rgb(0,0,0)">&nbsp;bit_mask</span><span style="COLOR: rgb(0,0,0)">&lt;</span><span style="COLOR: rgb(0,0,0)">null_type</span><span style="COLOR: rgb(0,0,0)">&gt;</span><span style="COLOR: rgb(0,0,0)"><br></span><span style="COLOR: rgb(0,128,128)">138</span>&nbsp;<span style="COLOR: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;{<br></span><span style="COLOR: rgb(0,128,128)">139</span>&nbsp;<span style="COLOR: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;details::bit_storage</span><span style="COLOR: rgb(0,0,0)">&lt;</span><span style="COLOR: rgb(0,0,0)">0</span><span style="COLOR: rgb(0,0,0)">&gt;</span><span style="COLOR: rgb(0,0,0)">::storage_type&nbsp;storage_type;<br></span><span style="COLOR: rgb(0,128,128)">140</span>&nbsp;<span style="COLOR: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: rgb(0,0,255)">static</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,255)">const</span><span style="COLOR: rgb(0,0,0)">&nbsp;storage_type&nbsp;value&nbsp;</span><span style="COLOR: rgb(0,0,0)">=</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">0</span><span style="COLOR: rgb(0,0,0)">;<br></span><span style="COLOR: rgb(0,128,128)">141</span>&nbsp;<span style="COLOR: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;};<br></span><span style="COLOR: rgb(0,128,128)">142</span>&nbsp;<span style="COLOR: rgb(0,0,0)"><br></span><span style="COLOR: rgb(0,128,128)">143</span>&nbsp;<span style="COLOR: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;<br></span><span style="COLOR: rgb(0,128,128)">144</span>&nbsp;<span style="COLOR: rgb(0,0,0)"><br></span><span style="COLOR: rgb(0,128,128)">145</span>&nbsp;<span style="COLOR: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;<br></span><span style="COLOR: rgb(0,128,128)">146</span>&nbsp;<span style="COLOR: rgb(0,0,0)"><br></span><span style="COLOR: rgb(0,128,128)">147</span>&nbsp;<span style="COLOR: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: rgb(0,0,255)">#define</span><span style="COLOR: rgb(0,0,0)">&nbsp;INT_LIST_1(n1)&nbsp;multi_bit_mask::int_list_t&lt;n1,&nbsp;multi_bit_mask::null_type&gt;</span><span style="COLOR: rgb(0,0,0)"><br></span><span style="COLOR: rgb(0,128,128)">148</span>&nbsp;<span style="COLOR: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: rgb(0,0,255)">#define</span><span style="COLOR: rgb(0,0,0)">&nbsp;INT_LIST_2(n1,&nbsp;n2)&nbsp;multi_bit_mask::int_list_t&lt;n1,&nbsp;INT_LIST_1(n2)&nbsp;&gt;&nbsp;</span><span style="COLOR: rgb(0,0,0)"><br></span><span style="COLOR: rgb(0,128,128)">149</span>&nbsp;<span style="COLOR: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: rgb(0,0,255)">#define</span><span style="COLOR: rgb(0,0,0)">&nbsp;INT_LIST_3(n1,&nbsp;n2,&nbsp;n3)&nbsp;multi_bit_mask::int_list_t&lt;n1,&nbsp;INT_LIST_2(n2,&nbsp;n3)&nbsp;&gt;&nbsp;</span><span style="COLOR: rgb(0,0,0)"><br></span><span style="COLOR: rgb(0,128,128)">150</span>&nbsp;<span style="COLOR: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: rgb(0,0,255)">#define</span><span style="COLOR: rgb(0,0,0)">&nbsp;INT_LIST_4(n1,&nbsp;n2,&nbsp;n3,&nbsp;n4)&nbsp;multi_bit_mask::int_list_t&lt;n1,&nbsp;INT_LIST_3(n2,&nbsp;n3,&nbsp;n4)&nbsp;&gt;&nbsp;</span><span style="COLOR: rgb(0,0,0)"><br></span><span style="COLOR: rgb(0,128,128)">151</span>&nbsp;<span style="COLOR: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: rgb(0,0,255)">#define</span><span style="COLOR: rgb(0,0,0)">&nbsp;INT_LIST_5(n1,&nbsp;n2,&nbsp;n3,&nbsp;n4,&nbsp;n5)&nbsp;multi_bit_mask::int_list_t&lt;n1,&nbsp;INT_LIST_4(n2,&nbsp;n3,&nbsp;n4,&nbsp;n5)&nbsp;&gt;&nbsp;</span><span style="COLOR: rgb(0,0,0)"><br></span><span style="COLOR: rgb(0,128,128)">152</span>&nbsp;<span style="COLOR: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: rgb(0,0,255)">#define</span><span style="COLOR: rgb(0,0,0)">&nbsp;INT_LIST_6(n1,&nbsp;n2,&nbsp;n3,&nbsp;n4,&nbsp;n5,&nbsp;n6)&nbsp;multi_bit_mask::int_list_t&lt;n1,&nbsp;INT_LIST_5(n2,&nbsp;n3,&nbsp;n4,&nbsp;n5,&nbsp;n6)&nbsp;&gt;&nbsp;</span><span style="COLOR: rgb(0,0,0)"><br></span><span style="COLOR: rgb(0,128,128)">153</span>&nbsp;<span style="COLOR: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: rgb(0,0,255)">#define</span><span style="COLOR: rgb(0,0,0)">&nbsp;INT_LIST_7(n1,&nbsp;n2,&nbsp;n3,&nbsp;n4,&nbsp;n5,&nbsp;n6,&nbsp;n7)&nbsp;multi_bit_mask::int_list_t&lt;n1,&nbsp;INT_LIST_6(n2,&nbsp;n3,&nbsp;n4,&nbsp;n5,&nbsp;n6,&nbsp;n7)&nbsp;&gt;&nbsp;</span><span style="COLOR: rgb(0,0,0)"><br></span><span style="COLOR: rgb(0,128,128)">154</span>&nbsp;<span style="COLOR: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: rgb(0,0,255)">#define</span><span style="COLOR: rgb(0,0,0)">&nbsp;INT_LIST_8(n1,&nbsp;n2,&nbsp;n3,&nbsp;n4,&nbsp;n5,&nbsp;n6,&nbsp;n7,&nbsp;n8)&nbsp;multi_bit_mask::int_list_t&lt;n1,&nbsp;INT_LIST_7(n2,&nbsp;n3,&nbsp;n4,&nbsp;n5,&nbsp;n6,&nbsp;n7,&nbsp;n8)&nbsp;&gt;&nbsp;</span><span style="COLOR: rgb(0,0,0)"><br></span><span style="COLOR: rgb(0,128,128)">155</span>&nbsp;<span style="COLOR: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;<br></span><span style="COLOR: rgb(0,128,128)">156</span>&nbsp;<span style="COLOR: rgb(0,0,0)">}<br></span><span style="COLOR: rgb(0,128,128)">157</span>&nbsp;<span style="COLOR: rgb(0,0,0)"><br></span><span style="COLOR: rgb(0,128,128)">158</span>&nbsp;<span style="COLOR: rgb(0,0,0)"><br></span><span style="COLOR: rgb(0,128,128)">159</span>&nbsp;<span style="COLOR: rgb(0,0,0)"></span></div>
<p><br>sample<br></p>
<div style="BORDER-RIGHT: rgb(204,204,204) 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: rgb(204,204,204) 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: rgb(204,204,204) 1px solid; WIDTH: 98%; PADDING-TOP: 4px; BORDER-BOTTOM: rgb(204,204,204) 1px solid; BACKGROUND-COLOR: rgb(238,238,238)"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top> <span style="COLOR: rgb(0,0,0)">#include&nbsp;</span> <span style="COLOR: rgb(0,0,0)">&lt;</span> <span style="COLOR: rgb(0,0,0)">iostream</span> <span style="COLOR: rgb(0,0,0)">&gt;</span> <span style="COLOR: rgb(0,0,0)"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>#include&nbsp;</span> <span style="COLOR: rgb(0,0,0)">"</span> <span style="COLOR: rgb(0,0,0)">multi_bit_mask.h</span> <span style="COLOR: rgb(0,0,0)">"</span> <span style="COLOR: rgb(0,0,0)"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top> </span><span style="COLOR: rgb(0,0,255)">using</span> <span style="COLOR: rgb(0,0,0)">&nbsp;</span> <span style="COLOR: rgb(0,0,255)">namespace</span> <span style="COLOR: rgb(0,0,0)">&nbsp;std;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span> <span style="COLOR: rgb(0,0,255)">int</span> <span style="COLOR: rgb(0,0,0)">&nbsp;main()<br><img id=Codehighlighter1_80_309_Open_Image onclick="this.style.display='none'; Codehighlighter1_80_309_Open_Text.style.display='none'; Codehighlighter1_80_309_Closed_Image.style.display='inline'; Codehighlighter1_80_309_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_80_309_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_80_309_Closed_Text.style.display='none'; Codehighlighter1_80_309_Open_Image.style.display='inline'; Codehighlighter1_80_309_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align=top></span> <span id=Codehighlighter1_80_309_Closed_Text style="BORDER-RIGHT: rgb(128,128,128) 1px solid; BORDER-TOP: rgb(128,128,128) 1px solid; DISPLAY: none; BORDER-LEFT: rgb(128,128,128) 1px solid; BORDER-BOTTOM: rgb(128,128,128) 1px solid; BACKGROUND-COLOR: rgb(255,255,255)"><img src="http://www.cppblog.com/Images/dot.gif"> </span><span id=Codehighlighter1_80_309_Open_Text><span style="COLOR: rgb(0,0,0)">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;cout&nbsp;</span> <span style="COLOR: rgb(0,0,0)">&lt;&lt;</span> <span style="COLOR: rgb(0,0,0)">&nbsp;multi_bit_mask::bit_mask</span> <span style="COLOR: rgb(0,0,0)">&lt;</span> <span style="COLOR: rgb(0,0,0)">INT_LIST_1(</span> <span style="COLOR: rgb(0,0,0)">1</span> <span style="COLOR: rgb(0,0,0)">)</span> <span style="COLOR: rgb(0,0,0)">&gt;</span> <span style="COLOR: rgb(0,0,0)">::value&nbsp;</span> <span style="COLOR: rgb(0,0,0)">&lt;&lt;</span> <span style="COLOR: rgb(0,0,0)">&nbsp;endl;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;cout&nbsp;</span> <span style="COLOR: rgb(0,0,0)">&lt;&lt;</span> <span style="COLOR: rgb(0,0,0)">&nbsp;multi_bit_mask::bit_mask</span> <span style="COLOR: rgb(0,0,0)">&lt;</span> <span style="COLOR: rgb(0,0,0)">INT_LIST_5(</span> <span style="COLOR: rgb(0,0,0)">0</span> <span style="COLOR: rgb(0,0,0)">,&nbsp;</span> <span style="COLOR: rgb(0,0,0)">1</span> <span style="COLOR: rgb(0,0,0)">,&nbsp;</span> <span style="COLOR: rgb(0,0,0)">2</span> <span style="COLOR: rgb(0,0,0)">,&nbsp;</span> <span style="COLOR: rgb(0,0,0)">3</span> <span style="COLOR: rgb(0,0,0)">,&nbsp;</span> <span style="COLOR: rgb(0,0,0)">4</span> <span style="COLOR: rgb(0,0,0)">)</span> <span style="COLOR: rgb(0,0,0)">&gt;</span> <span style="COLOR: rgb(0,0,0)">::value&nbsp;</span> <span style="COLOR: rgb(0,0,0)">&lt;&lt;</span> <span style="COLOR: rgb(0,0,0)">&nbsp;endl;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;cout&nbsp;</span> <span style="COLOR: rgb(0,0,0)">&lt;&lt;</span> <span style="COLOR: rgb(0,0,0)">&nbsp;multi_bit_mask::bit_mask</span> <span style="COLOR: rgb(0,0,0)">&lt;</span> <span style="COLOR: rgb(0,0,0)">INT_LIST_7(</span> <span style="COLOR: rgb(0,0,0)">0</span> <span style="COLOR: rgb(0,0,0)">,&nbsp;</span> <span style="COLOR: rgb(0,0,0)">1</span> <span style="COLOR: rgb(0,0,0)">,&nbsp;</span> <span style="COLOR: rgb(0,0,0)">2</span> <span style="COLOR: rgb(0,0,0)">,&nbsp;</span> <span style="COLOR: rgb(0,0,0)">3</span> <span style="COLOR: rgb(0,0,0)">,&nbsp;</span> <span style="COLOR: rgb(0,0,0)">4</span> <span style="COLOR: rgb(0,0,0)">,&nbsp;</span> <span style="COLOR: rgb(0,0,0)">4</span> <span style="COLOR: rgb(0,0,0)">,&nbsp;</span> <span style="COLOR: rgb(0,0,0)">2</span> <span style="COLOR: rgb(0,0,0)">)</span> <span style="COLOR: rgb(0,0,0)">&gt;</span> <span style="COLOR: rgb(0,0,0)">::value&nbsp;</span> <span style="COLOR: rgb(0,0,0)">&lt;&lt;</span> <span style="COLOR: rgb(0,0,0)">&nbsp;endl;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top></span> </span></div>
<img src ="http://www.cppblog.com/shifan3/aggbug/14264.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/shifan3/" target="_blank">shifan3</a> 2006-10-26 23:37 <a href="http://www.cppblog.com/shifan3/archive/2006/10/26/14264.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[yc]VC下typeid实现及内存布局分析</title><link>http://www.cppblog.com/shifan3/archive/2006/10/26/14187.html</link><dc:creator>shifan3</dc:creator><author>shifan3</author><pubDate>Thu, 26 Oct 2006 02:46:00 GMT</pubDate><guid>http://www.cppblog.com/shifan3/archive/2006/10/26/14187.html</guid><wfw:comment>http://www.cppblog.com/shifan3/comments/14187.html</wfw:comment><comments>http://www.cppblog.com/shifan3/archive/2006/10/26/14187.html#Feedback</comments><slash:comments>5</slash:comments><wfw:commentRss>http://www.cppblog.com/shifan3/comments/commentRss/14187.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/shifan3/services/trackbacks/14187.html</trackback:ping><description><![CDATA[<p>&nbsp;&nbsp;&nbsp; 近日在学校bbs上与人讨论C++的typeid关键字的实现问题，有人提到type_info的地址是存放在虚表的第一个位置上，颇觉得不妥，于是我在vc2003下实验了一番</p>
<p>&nbsp;&nbsp;&nbsp; 在vc下，使用typeid的时候，如果typeid施加给的类型是没有vptr的class或者根本不是class<br>那么汇编是<br>mov&nbsp; dword ptr [addr],offset A `RTTI Type Descriptor' (42AD40h)<br>也就是编译器生成一个简单的type_info对象的表，并且在编译期静态决定下标，做一个简单查表操作。<br></p>
<p>如果typeid的操作对象是具有vptr的class，但是并不是一个引用或者指针的解引用形式，例如<br></p>
<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: #000000">A&nbsp;a;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>typeid(a);</span> </div>
<p><br>那么仍然仅仅会做查表操作<br><br><br>如果typeid的操作对象是具有vptr的class，并且是引用或者指针的解引用形式，例如<br></p>
<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: #000000">A&nbsp;</span> <span style="COLOR: #000000">*</span> <span style="COLOR: #000000">p&nbsp;</span> <span style="COLOR: #000000">=</span> <span style="COLOR: #000000">&nbsp;</span> <span style="COLOR: #0000ff">new</span> <span style="COLOR: #000000">&nbsp;A;<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">&nbsp;r&nbsp;</span> <span style="COLOR: #000000">=</span> <span style="COLOR: #000000">&nbsp;</span> <span style="COLOR: #000000">*</span> <span style="COLOR: #000000">p;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>typeid(</span> <span style="COLOR: #000000">*</span> <span style="COLOR: #000000">p);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>typeid(r);</span> </div>
<p><br>那么就会调用一个叫___RTtypeid的函数，并通过某种方法来获取type_info对象<br>下面是___RTtypeid的反汇编，这里只列出关键的几条指令<br></p>
<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: #000000">0041213E&nbsp;&nbsp;mov&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ecx,dword&nbsp;ptr&nbsp;[inptr]&nbsp;&nbsp;&nbsp;&nbsp;；inptr是对象的地址<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span> <span style="COLOR: #000000">00412141</span> <span style="COLOR: #000000">&nbsp;&nbsp;mov&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;edx,dword&nbsp;ptr&nbsp;[ecx]&nbsp;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span> <span style="COLOR: #000000">00412143</span> <span style="COLOR: #000000">&nbsp;&nbsp;mov&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;eax,dword&nbsp;ptr&nbsp;[edx</span> <span style="COLOR: #000000">-</span> <span style="COLOR: #000000">4</span> <span style="COLOR: #000000">]&nbsp;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>0041215F&nbsp;&nbsp;mov&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ecx,dword&nbsp;ptr&nbsp;[eax</span> <span style="COLOR: #000000">+</span> <span style="COLOR: #000000">0Ch]&nbsp;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span> <span style="COLOR: #000000">00412162</span> <span style="COLOR: #000000">&nbsp;&nbsp;mov&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dword&nbsp;ptr&nbsp;[ebp</span> <span style="COLOR: #000000">-</span> <span style="COLOR: #000000">48h],ecx&nbsp;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>0041216C&nbsp;&nbsp;mov&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;eax,dword&nbsp;ptr&nbsp;[ebp</span> <span style="COLOR: #000000">-</span> <span style="COLOR: #000000">48h]&nbsp;</span> </div>
<p><br>基本上等价于C语言的<br></p>
<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">int</span> <span style="COLOR: #000000">&nbsp;a1&nbsp;</span> <span style="COLOR: #000000">=</span> <span style="COLOR: #000000">&nbsp;(</span> <span style="COLOR: #0000ff">int</span> <span style="COLOR: #000000">)p;&nbsp;</span> <span style="COLOR: #008000">//</span> <span style="COLOR: #008000">p是对象的地址</span> <span style="COLOR: #008000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top> </span><span style="COLOR: #0000ff">int</span> <span style="COLOR: #000000">&nbsp;a2&nbsp;</span> <span style="COLOR: #000000">=</span> <span style="COLOR: #000000">&nbsp;</span> <span style="COLOR: #000000">*</span> <span style="COLOR: #000000">(</span> <span style="COLOR: #0000ff">int</span> <span style="COLOR: #000000">*</span> <span style="COLOR: #000000">)a1&nbsp;</span> <span style="COLOR: #000000">-</span> <span style="COLOR: #000000">&nbsp;</span> <span style="COLOR: #000000">4</span> <span style="COLOR: #000000">;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span> <span style="COLOR: #0000ff">int</span> <span style="COLOR: #000000">&nbsp;a3&nbsp;</span> <span style="COLOR: #000000">=</span> <span style="COLOR: #000000">&nbsp;</span> <span style="COLOR: #000000">*</span> <span style="COLOR: #000000">(</span> <span style="COLOR: #0000ff">int</span> <span style="COLOR: #000000">*</span> <span style="COLOR: #000000">)a2&nbsp;</span> <span style="COLOR: #000000">+</span> <span style="COLOR: #000000">&nbsp;</span> <span style="COLOR: #000000">12</span> <span style="COLOR: #000000">;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span> <span style="COLOR: #0000ff">int</span> <span style="COLOR: #000000">&nbsp;a4&nbsp;</span> <span style="COLOR: #000000">=</span> <span style="COLOR: #000000">&nbsp;</span> <span style="COLOR: #000000">*</span> <span style="COLOR: #000000">(</span> <span style="COLOR: #0000ff">int</span> <span style="COLOR: #000000">*</span> <span style="COLOR: #000000">)a3;</span> </div>
<p>&nbsp;</p>
<p>那么从这段代码可以看出vc下type_info对象的存放位置[如下图]</p>
<p><img src="http://www.cppblog.com/images/cppblog_com/shifan3/2879/r_1.JPG"> <br></p>
<p><br>也就虚表下标为-1的位置上存放了一个指向一个未知的表的指针(暂且将此表命名为runtime_info_table)<br>runtime_info_table的第4格上存放了type_info对象的地址<br>至于runtime_info_table里前3格上存放的是什么, 还需要再研究研究<br>一般来说它们全是0, 但是对于多重虚继承的类, 第二格上会是4, 可能和指针的偏移量有关.<br></p>
<img src ="http://www.cppblog.com/shifan3/aggbug/14187.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/shifan3/" target="_blank">shifan3</a> 2006-10-26 10:46 <a href="http://www.cppblog.com/shifan3/archive/2006/10/26/14187.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[yc]Xpressive简介</title><link>http://www.cppblog.com/shifan3/archive/2006/07/27/10590.html</link><dc:creator>shifan3</dc:creator><author>shifan3</author><pubDate>Thu, 27 Jul 2006 08:27:00 GMT</pubDate><guid>http://www.cppblog.com/shifan3/archive/2006/07/27/10590.html</guid><wfw:comment>http://www.cppblog.com/shifan3/comments/10590.html</wfw:comment><comments>http://www.cppblog.com/shifan3/archive/2006/07/27/10590.html#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://www.cppblog.com/shifan3/comments/commentRss/10590.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/shifan3/services/trackbacks/10590.html</trackback:ping><description><![CDATA[Xpressive是一个C++的正则表达式库，目前是Boost的候选库。<br>Xpressive和Boost.Regex的区别很大。首先，Xpressive是一个纯头文件的库，也是说，在使用之前不需要预先编译。其次，Xpressive支持类似于Spirit的静态语义定义。<br><br>我们先来看一个例子：
<p>&#160;</p>
<div style="BORDER-RIGHT: rgb(204,204,204) 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: rgb(204,204,204) 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: rgb(204,204,204) 1px solid; WIDTH: 98%; PADDING-TOP: 4px; BORDER-BOTTOM: rgb(204,204,204) 1px solid; BACKGROUND-COLOR: rgb(238,238,238)"><span style="COLOR: rgb(0,0,0)">#include&nbsp;</span><span style="COLOR: rgb(0,0,0)">&lt;</span><span style="COLOR: rgb(0,0,0)">iostream</span><span style="COLOR: rgb(0,0,0)">&gt;</span><span style="COLOR: rgb(0,0,0)"><br>#include&nbsp;</span><span style="COLOR: rgb(0,0,0)">&lt;</span><span style="COLOR: rgb(0,0,0)">boost</span><span style="COLOR: rgb(0,0,0)">/</span><span style="COLOR: rgb(0,0,0)">xpressive</span><span style="COLOR: rgb(0,0,0)">/</span><span style="COLOR: rgb(0,0,0)">xpressive.hpp</span><span style="COLOR: rgb(0,0,0)">&gt;</span><span style="COLOR: rgb(0,0,0)"><br><br></span><span style="COLOR: rgb(0,0,255)">using</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,255)">namespace</span><span style="COLOR: rgb(0,0,0)">&nbsp;boost::xpressive;<br><br></span><span style="COLOR: rgb(0,0,255)">int</span><span style="COLOR: rgb(0,0,0)">&nbsp;main()<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;std::</span><span style="COLOR: rgb(0,0,255)">string</span><span style="COLOR: rgb(0,0,0)">&nbsp;hello(&nbsp;</span><span style="COLOR: rgb(0,0,0)">"</span><span style="COLOR: rgb(0,0,0)">hello&nbsp;world!</span><span style="COLOR: rgb(0,0,0)">"</span><span style="COLOR: rgb(0,0,0)">&nbsp;);<br><br>&nbsp;&nbsp;&nbsp;&nbsp;sregex&nbsp;rex&nbsp;</span><span style="COLOR: rgb(0,0,0)">=</span><span style="COLOR: rgb(0,0,0)">&nbsp;sregex::compile(&nbsp;</span><span style="COLOR: rgb(0,0,0)">"</span><span style="COLOR: rgb(0,0,0)">(\\w+)&nbsp;(\\w+)!</span><span style="COLOR: rgb(0,0,0)">"</span><span style="COLOR: rgb(0,0,0)">&nbsp;);<br>&nbsp;&nbsp;&nbsp;&nbsp;smatch&nbsp;what;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: rgb(0,0,255)">if</span><span style="COLOR: rgb(0,0,0)">(&nbsp;regex_match(&nbsp;hello,&nbsp;what,&nbsp;rex&nbsp;)&nbsp;)<br>&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;std::cout&nbsp;</span><span style="COLOR: rgb(0,0,0)">&lt;&lt;</span><span style="COLOR: rgb(0,0,0)">&nbsp;what[</span><span style="COLOR: rgb(0,0,0)">0</span><span style="COLOR: rgb(0,0,0)">]&nbsp;</span><span style="COLOR: rgb(0,0,0)">&lt;&lt;</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">'</span><span style="COLOR: rgb(0,0,0)">\n</span><span style="COLOR: rgb(0,0,0)">'</span><span style="COLOR: rgb(0,0,0)">;&nbsp;</span><span style="COLOR: rgb(0,128,0)">//</span><span style="COLOR: rgb(0,128,0)">&nbsp;whole&nbsp;match</span><span style="COLOR: rgb(0,128,0)"><br></span><span style="COLOR: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;std::cout&nbsp;</span><span style="COLOR: rgb(0,0,0)">&lt;&lt;</span><span style="COLOR: rgb(0,0,0)">&nbsp;what[</span><span style="COLOR: rgb(0,0,0)">1</span><span style="COLOR: rgb(0,0,0)">]&nbsp;</span><span style="COLOR: rgb(0,0,0)">&lt;&lt;</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">'</span><span style="COLOR: rgb(0,0,0)">\n</span><span style="COLOR: rgb(0,0,0)">'</span><span style="COLOR: rgb(0,0,0)">;&nbsp;</span><span style="COLOR: rgb(0,128,0)">//</span><span style="COLOR: rgb(0,128,0)">&nbsp;first&nbsp;capture</span><span style="COLOR: rgb(0,128,0)"><br></span><span style="COLOR: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;std::cout&nbsp;</span><span style="COLOR: rgb(0,0,0)">&lt;&lt;</span><span style="COLOR: rgb(0,0,0)">&nbsp;what[</span><span style="COLOR: rgb(0,0,0)">2</span><span style="COLOR: rgb(0,0,0)">]&nbsp;</span><span style="COLOR: rgb(0,0,0)">&lt;&lt;</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">'</span><span style="COLOR: rgb(0,0,0)">\n</span><span style="COLOR: rgb(0,0,0)">'</span><span style="COLOR: rgb(0,0,0)">;&nbsp;</span><span style="COLOR: rgb(0,128,0)">//</span><span style="COLOR: rgb(0,128,0)">&nbsp;second&nbsp;capture</span><span style="COLOR: rgb(0,128,0)"><br></span><span style="COLOR: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;}<br><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: rgb(0,0,255)">return</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">0</span><span style="COLOR: rgb(0,0,0)">;<br>}</span></div>
<p>这是使用Xpressive动态语义定义的例子，其中sregex::compile函数编译一个表示正则文法的串，并返回一个正则对象sregex<br>使用regex_match来使用这个正则对象匹配一个串。结果储存在what内<br>其中what[0]返回整个串，what[1]~what[n]返回文法中用于标记的部分(用小括号括起来的部分)<br>最后将输出<br>&nbsp;&nbsp;&nbsp;&nbsp; hello world!<br>&nbsp;&nbsp;&nbsp;&nbsp; hello<br>&nbsp;&nbsp;&nbsp;&nbsp; world</p>
<p>如果想在一个串中查找符合该文法的子串，可以使用regex_search，用法和regex_match一样，此外还可以用regex_replace来进行替换。<br></p>
<p>&nbsp;</p>
<p><br>静态文法：<br>Xpressive除了可以用compile来分析一个文法串之外，还可以用类似于Spirit的方式来静态的指定文法：<br></p>
<div style="BORDER-RIGHT: rgb(204,204,204) 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: rgb(204,204,204) 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: rgb(204,204,204) 1px solid; WIDTH: 98%; PADDING-TOP: 4px; BORDER-BOTTOM: rgb(204,204,204) 1px solid; BACKGROUND-COLOR: rgb(238,238,238)"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: rgb(0,0,0)">sregex&nbsp;re&nbsp;</span><span style="COLOR: rgb(0,0,0)">=</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">'</span><span style="COLOR: rgb(0,0,0)">$</span><span style="COLOR: rgb(0,0,0)">'</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">&gt;&gt;</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">+</span><span style="COLOR: rgb(0,0,0)">_d&nbsp;</span><span style="COLOR: rgb(0,0,0)">&gt;&gt;</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">'</span><span style="COLOR: rgb(0,0,0)">.</span><span style="COLOR: rgb(0,0,0)">'</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">&gt;&gt;</span><span style="COLOR: rgb(0,0,0)">&nbsp;_d&nbsp;</span><span style="COLOR: rgb(0,0,0)">&gt;&gt;</span><span style="COLOR: rgb(0,0,0)">&nbsp;_d;</span></div>
<p>这将定义一个表示金额的串，其中_d表示一个数字，相当于串 $\d+.\d\d<br>这样定义文法将比之前的动态定义更加高效，并且还有一个附加的好处：<br>分级定义：</p>
<div style="BORDER-RIGHT: rgb(204,204,204) 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: rgb(204,204,204) 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: rgb(204,204,204) 1px solid; WIDTH: 98%; PADDING-TOP: 4px; BORDER-BOTTOM: rgb(204,204,204) 1px solid; BACKGROUND-COLOR: rgb(238,238,238)"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: rgb(0,0,0)">sregex&nbsp;re&nbsp;</span><span style="COLOR: rgb(0,0,0)">=</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">'</span><span style="COLOR: rgb(0,0,0)">$</span><span style="COLOR: rgb(0,0,0)">'</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">&gt;&gt;</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">+</span><span style="COLOR: rgb(0,0,0)">_d&nbsp;</span><span style="COLOR: rgb(0,0,0)">&gt;&gt;</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">'</span><span style="COLOR: rgb(0,0,0)">.</span><span style="COLOR: rgb(0,0,0)">'</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">&gt;&gt;</span><span style="COLOR: rgb(0,0,0)">&nbsp;_d&nbsp;</span><span style="COLOR: rgb(0,0,0)">&gt;&gt;</span><span style="COLOR: rgb(0,0,0)">&nbsp;_d;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>sregex&nbsp;s&nbsp;</span><span style="COLOR: rgb(0,0,0)">=</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">'</span><span style="COLOR: rgb(0,0,0)">(</span><span style="COLOR: rgb(0,0,0)">'</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">&gt;&gt;</span><span style="COLOR: rgb(0,0,0)">&nbsp;re&nbsp;</span><span style="COLOR: rgb(0,0,0)">&gt;&gt;</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">'</span><span style="COLOR: rgb(0,0,0)">)</span><span style="COLOR: rgb(0,0,0)">'</span><span style="COLOR: rgb(0,0,0)">;</span></div>
<p>这样s表示为用括号括起来的re<br>通过分级定义，文法能被表示的更加清楚。<br>更加棒的是，分级定义还可以向后引用，因此能够分析EBNF</p>
<div style="BORDER-RIGHT: rgb(204,204,204) 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: rgb(204,204,204) 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: rgb(204,204,204) 1px solid; WIDTH: 98%; PADDING-TOP: 4px; BORDER-BOTTOM: rgb(204,204,204) 1px solid; BACKGROUND-COLOR: rgb(238,238,238)"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: rgb(0,0,0)">sregex&nbsp;group,&nbsp;factor,&nbsp;term,&nbsp;expression;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>group&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: rgb(0,0,0)">=</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">'</span><span style="COLOR: rgb(0,0,0)">(</span><span style="COLOR: rgb(0,0,0)">'</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">&gt;&gt;</span><span style="COLOR: rgb(0,0,0)">&nbsp;by_ref(expression)&nbsp;</span><span style="COLOR: rgb(0,0,0)">&gt;&gt;</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">'</span><span style="COLOR: rgb(0,0,0)">)</span><span style="COLOR: rgb(0,0,0)">'</span><span style="COLOR: rgb(0,0,0)">;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>factor&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: rgb(0,0,0)">=</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">+</span><span style="COLOR: rgb(0,0,0)">_d&nbsp;</span><span style="COLOR: rgb(0,0,0)">|</span><span style="COLOR: rgb(0,0,0)">&nbsp;group;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>term&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: rgb(0,0,0)">=</span><span style="COLOR: rgb(0,0,0)">&nbsp;factor&nbsp;</span><span style="COLOR: rgb(0,0,0)">&gt;&gt;</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">*</span><span style="COLOR: rgb(0,0,0)">((</span><span style="COLOR: rgb(0,0,0)">'</span><span style="COLOR: rgb(0,0,0)">*</span><span style="COLOR: rgb(0,0,0)">'</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">&gt;&gt;</span><span style="COLOR: rgb(0,0,0)">&nbsp;factor)&nbsp;</span><span style="COLOR: rgb(0,0,0)">|</span><span style="COLOR: rgb(0,0,0)">&nbsp;(</span><span style="COLOR: rgb(0,0,0)">'</span><span style="COLOR: rgb(0,0,0)">/</span><span style="COLOR: rgb(0,0,0)">'</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">&gt;&gt;</span><span style="COLOR: rgb(0,0,0)">&nbsp;factor));<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>expression&nbsp;&nbsp;</span><span style="COLOR: rgb(0,0,0)">=</span><span style="COLOR: rgb(0,0,0)">&nbsp;term&nbsp;</span><span style="COLOR: rgb(0,0,0)">&gt;&gt;</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">*</span><span style="COLOR: rgb(0,0,0)">((</span><span style="COLOR: rgb(0,0,0)">'</span><span style="COLOR: rgb(0,0,0)">+</span><span style="COLOR: rgb(0,0,0)">'</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">&gt;&gt;</span><span style="COLOR: rgb(0,0,0)">&nbsp;term)&nbsp;</span><span style="COLOR: rgb(0,0,0)">|</span><span style="COLOR: rgb(0,0,0)">&nbsp;(</span><span style="COLOR: rgb(0,0,0)">'</span><span style="COLOR: rgb(0,0,0)">-</span><span style="COLOR: rgb(0,0,0)">'</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">&gt;&gt;</span><span style="COLOR: rgb(0,0,0)">&nbsp;term));</span></div>
<p>expression定义了一个四则表达式，注意其中group的定义。<br>这里必须使用by_ref是因为Xpressive默认是值拷贝，如果这里使用默认的方式，那么会造成一个无限循环。<br><br><br>Xpressive可以在这里下载<br><a href="http://boost-consulting.com/vault/index.php?PHPSESSID=f1d4af8b742cfa7adae7aab373cfc535&amp;direction=0&amp;order=&amp;directory=Strings%20-%20Text%20Processing&amp;PHPSESSID=f1d4af8b742cfa7adae7aab373cfc535">http://boost-consulting.com/vault/index.php?PHPSESSID=f1d4af8b742cfa7adae7aab373cfc535&amp;direction=0&amp;order=&amp;directory=Strings%20-%20Text%20Processing&amp;PHPSESSID=f1d4af8b742cfa7adae7aab373cfc535</a><br>内有详细的文档</p>
<img src ="http://www.cppblog.com/shifan3/aggbug/10590.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/shifan3/" target="_blank">shifan3</a> 2006-07-27 16:27 <a href="http://www.cppblog.com/shifan3/archive/2006/07/27/10590.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[yc]乱序Policy手法</title><link>http://www.cppblog.com/shifan3/archive/2006/07/24/10384.html</link><dc:creator>shifan3</dc:creator><author>shifan3</author><pubDate>Sun, 23 Jul 2006 17:06:00 GMT</pubDate><guid>http://www.cppblog.com/shifan3/archive/2006/07/24/10384.html</guid><wfw:comment>http://www.cppblog.com/shifan3/comments/10384.html</wfw:comment><comments>http://www.cppblog.com/shifan3/archive/2006/07/24/10384.html#Feedback</comments><slash:comments>8</slash:comments><wfw:commentRss>http://www.cppblog.com/shifan3/comments/commentRss/10384.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/shifan3/services/trackbacks/10384.html</trackback:ping><description><![CDATA[<p>看了<a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#53;&#52;&#54;&#64;&#67;&#43;&#43;&#64;&#70;&#114;&#101;&#101;&#99;&#105;&#116;&#121;">546@C++@Freecity</a>之后，发觉非常有意思,由此产生一些想法</p>
<p>很多时候写一个类的时候，需要多个模版参数，例如一个遗传算法的算法类，需要一个模版参数来指定交配方式，另一个模版参数来指定子代选择的方式，还要一个参数来指定变异的方式。那么一般来说，这个类会写成：</p>
<p>template&lt;class T&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;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //描述问题的一个类<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; , class CrossPolicy = AvgCrossPolicy&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //杂交方式<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; , class SelectPolicy = DefaultSelectPolicy&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //子代选择的方式<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; , class VariationPolicy = ReverseVariationPolicy&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //变异方式<br>class Gene <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : private AvgCrossPolicy<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; , private SelectPolicy<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; , private VariationPolicy<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ....<br>};</p>
<p>这样用户要使用该类的时候，可以直接指定T，就行了，然而如果要指定变异方式，那么就必须把所有的参数都显式的写出来，很不方便</p>
<p>546提供了一种有效的方法，可以让我们仅仅指定变异参数，而不用写出另两个Policy<br>甚至允许我们以任意的顺序书写几个Policy参数，都不会有问题</p>
<p>预备知识:<br>TypeList<br>一个TypeList是一个类型的容器<br>template &lt;typename Type_, typename Next_&gt;<br>struct TypeList<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; typedef Type_ Type;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; typedef Next_ Next;<br>};<br>这就是一个TypeList。<br>看这个写法，是不是像一个链表？<br>首先定义一个类型来表示链表尾：class NullType{};<br>现在一个包含了2个类型的TypeList就可以写为：<br>TypeList&lt;T1, TypeList&lt;T2, NullType&gt;&nbsp; &gt;</p>
<p>如何在一个TypeList中查找一个类型的子类？<br>首先要有一个IsDerivedFrom&lt;Base, T&gt;<br>这个比较简单<br>template&lt;class Base, class T&gt; <br>class IsDerivedFrom<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct large{char a[2];};<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; static char pred(Base*);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; static large pred(...);<br>public:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; enum {Is = sizeof(pred((T*)0)) == sizeof(char)};<br>};</p>
<p>然后FindChild就容易了<br>template &lt;class List, class Base&gt;<br>struct FindChild<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; template &lt;bool IsChild&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct Select<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; typedef typename List::Type Type;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; };</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; template &lt;&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct Select&lt;false&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; typedef typename FindChild&lt;typename List::Next, Base&gt;::Type Type;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; };</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; typedef typename Select&lt;IsDerivedFrom&lt;Base, typename List::Type&gt; &gt;::Type Type; <br>};</p>
<p>当然还要对一些特殊情况进行特化，例如NullType<br>template &lt;class Base&gt;<br>struct FindChild&lt;NullType, Base&gt;<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; typedef NullType Type;<br>};<br>这里使用NullType来表明没找到</p>
<p>实际操作：<br>首先需要给3个Policy3个基类，分别叫<br>class AvgCrossPolicyBase{};<br>class SelectPolicyBase{};<br>class VariationPolicyBase{};<br>内容为空就行了，这样也没有虚函数调用的开销</p>
<p><br>然后声明一个类来表示默认情况：<br>class DefaultPolicy{};</p>
<p>定义一个宏<br>#define TYPELIST_3_N(a, b, c) TypeList&lt;a, TypeList&lt;b, TypeList&lt;c, NullType&gt; &gt; &gt;</p>
<p>下面要写一些选择器,用于把合适的类型选择出来，如果没找到，则要使用默认的类型<br>template &lt;class List, class Base, class DefaultType&gt;<br>struct Selector<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; template &lt;class RetType&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct Judge<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; typedef RetType Type;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; };<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; template&lt;&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct Judge&lt;NullType&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; typedef DefaultType Type;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; };<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; typedef typename Judge&lt;typename FindChild&lt;List, Base&gt;::Type &gt;::Type Type;<br>};</p>
<p>好啦，现在整个类的声明可以写为</p>
<p>template&lt;class T<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; , class CrossPolicy_ = DefaultPolicy<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; , class SelectPolicy_ = DefaultPolicy<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; , class VariationPolicy_ = DefaultPolicy&nbsp;&nbsp;&nbsp;&nbsp; //其后的参数用户不可指定<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; , class List = TYPELIST_3_N(CrossPolicy_, SelectPolicy_, VariationPolicy_)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; , class CrossPolicy = typename Selector&lt;List, CrossPolicyBase,&nbsp; AvgCrossPolicy&gt;::Type<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; , class SelectPolicy = typename Selector&lt;List,&nbsp; SelectPolicyBase,&nbsp; DefaultSelectPolicy&gt;::Type<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; , class VariationPolicy = typename Selector&lt;List,&nbsp; VariationPolicyBase,&nbsp; ReverseVariationPolicy&gt;::Type<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &gt;<br>class Gene <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : private CrossPolicy<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; , private SelectPolicy<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; , private VariationPolicy<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ....<br>};</p>
<p><br>其中第4-7个参数（List，CrossPolicy，SelectPolicy和VariationPolicy）是不由用户指定的，仅仅是为了起一个别名<br>第一个参数T必须指定，然后2，3，4这3个参数就可以任意的改变顺序了<br>例如，可以写Gene&lt;T, DefaultSelectPolicy, AvgCrossPolicy&gt;而不会有任何问题<br>如果不想要最后面几个参数的话也行，但是代码就要稍微长一点<br>而且最好在类里面进行3个typedef<br>typedef typename Selector&lt;List, CrossPolicyBase,&nbsp; AvgCrossPolicy&gt;::Type CrossPolicy;<br>等，以便在实现的时候使用</p>
<img src ="http://www.cppblog.com/shifan3/aggbug/10384.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/shifan3/" target="_blank">shifan3</a> 2006-07-24 01:06 <a href="http://www.cppblog.com/shifan3/archive/2006/07/24/10384.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[yc]自己实现Lambda（第二部分）</title><link>http://www.cppblog.com/shifan3/archive/2006/07/15/10099.html</link><dc:creator>shifan3</dc:creator><author>shifan3</author><pubDate>Sat, 15 Jul 2006 07:32:00 GMT</pubDate><guid>http://www.cppblog.com/shifan3/archive/2006/07/15/10099.html</guid><wfw:comment>http://www.cppblog.com/shifan3/comments/10099.html</wfw:comment><comments>http://www.cppblog.com/shifan3/archive/2006/07/15/10099.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/shifan3/comments/commentRss/10099.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/shifan3/services/trackbacks/10099.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 发信人: shifan (家没有豚豚 T.T), 板面: C++标&nbsp; 题: 如何实现Lambda[第二部分]发信站: 飘渺水云间 (Thu Jun&nbsp; 8 23:30:20 2006), 转信章节:八:第一部分的小结九:简化,如何减少Lambda代码的冗余和依赖性十:bind的实现十一:实现phoenix八．&nbsp;&nbsp;&nbsp; 中期总结目前的结果是这样的...&nbsp;&nbsp;<a href='http://www.cppblog.com/shifan3/archive/2006/07/15/10099.html'>阅读全文</a><img src ="http://www.cppblog.com/shifan3/aggbug/10099.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/shifan3/" target="_blank">shifan3</a> 2006-07-15 15:32 <a href="http://www.cppblog.com/shifan3/archive/2006/07/15/10099.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[yc]自己实现Lambda</title><link>http://www.cppblog.com/shifan3/archive/2006/06/09/8334.html</link><dc:creator>shifan3</dc:creator><author>shifan3</author><pubDate>Fri, 09 Jun 2006 05:23:00 GMT</pubDate><guid>http://www.cppblog.com/shifan3/archive/2006/06/09/8334.html</guid><wfw:comment>http://www.cppblog.com/shifan3/comments/8334.html</wfw:comment><comments>http://www.cppblog.com/shifan3/archive/2006/06/09/8334.html#Feedback</comments><slash:comments>6</slash:comments><wfw:commentRss>http://www.cppblog.com/shifan3/comments/commentRss/8334.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/shifan3/services/trackbacks/8334.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 一．&nbsp;什么是Lambda所谓Lambda，简单的说就是快速的小函数生成。在C++中，STL的很多算法都要求使用者提供一个函数对象。例如for_each函数，会要求用户提供一个表明&#8220;行为&#8221;的函数对象。以vector&lt;bool&gt;为例，如果想使用for_each对其中的各元素全部赋值为true，一般需要这么一个函数对象，&nbsp; &nbsp; c...&nbsp;&nbsp;<a href='http://www.cppblog.com/shifan3/archive/2006/06/09/8334.html'>阅读全文</a><img src ="http://www.cppblog.com/shifan3/aggbug/8334.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/shifan3/" target="_blank">shifan3</a> 2006-06-09 13:23 <a href="http://www.cppblog.com/shifan3/archive/2006/06/09/8334.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[yc]boost::spirit初体验</title><link>http://www.cppblog.com/shifan3/archive/2005/12/18/1857.html</link><dc:creator>shifan3</dc:creator><author>shifan3</author><pubDate>Sun, 18 Dec 2005 04:02:00 GMT</pubDate><guid>http://www.cppblog.com/shifan3/archive/2005/12/18/1857.html</guid><wfw:comment>http://www.cppblog.com/shifan3/comments/1857.html</wfw:comment><comments>http://www.cppblog.com/shifan3/archive/2005/12/18/1857.html#Feedback</comments><slash:comments>5</slash:comments><wfw:commentRss>http://www.cppblog.com/shifan3/comments/commentRss/1857.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/shifan3/services/trackbacks/1857.html</trackback:ping><description><![CDATA[<p><font face="Courier New">&nbsp;&nbsp;&nbsp; 最近为了解析SQL语法，怀着试一试的心态去翻了翻boost的spirit库，因为该库的文档的简介里写着LL parser framework&nbsp; represents parsers directly as EBNF grammars in inlined C++。看着framework这个词自然觉得这个库很牛B，试用了一下果然如此。<br>&nbsp;&nbsp;&nbsp; 所谓EBNF即扩展巴克斯范式，是一种描述Context-Free Language的文法。在目前常见的非自然语言中，大部分都可以用EBNF表示。例如：<br><span class=identifier>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;group&nbsp;&nbsp;</span><span class=special>::=</span><span class=literal>'('</span><span class=identifier><span class=identifier>exp </span></span></font><font face="Courier New"><span class=literal>')'<br></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=identifier>factor&nbsp;</span><span class=special>::=</span><span class=identifier>integer</span><span class=special>|</span></font> <font face="Courier New"><span class=identifier>group<br></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=identifier>term&nbsp;&nbsp;&nbsp;</span><span class=special>::=</span><span class=identifier>factor</span><span class=special>((</span><span class=literal>'*'</span><span class=identifier>factor</span><span class=special>)</span><span class=special>|</span><span class=special>(</span><span class=literal>'/'</span><span class=identifier>factor</span></font> <font face="Courier New"><span class=special>))*<br></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=identifier>exp&nbsp;&nbsp;&nbsp;&nbsp;</span><span class=special>::=</span><span class=identifier>term</span><span class=special>((</span><span class=literal>'+'</span><span class=identifier>term</span><span class=special>)</span><span class=special>|</span><span class=special>(</span><span class=literal>'-'</span><span class=identifier>term</span></font> <span class=special><font face="Courier New">))*<br>这是一个整数表达式的EBNF。该段描述用spirit在C++中的实现则是：<br>&nbsp;&nbsp;&nbsp;</font> </span></p>
<div style="BORDER-RIGHT: rgb(204,204,204) 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: rgb(204,204,204) 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: rgb(204,204,204) 1px solid; WIDTH: 98%; PADDING-TOP: 4px; BORDER-BOTTOM: rgb(204,204,204) 1px solid; BACKGROUND-COLOR: rgb(238,238,238)"><font face="Courier New">&nbsp;&nbsp;&nbsp;<img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: rgb(0,0,0)">rule</span><span style="COLOR: rgb(0,0,0)">&lt;&gt;</span><span style="COLOR: rgb(0,0,0)">&nbsp;group,&nbsp;factor,&nbsp;term,&nbsp;exp;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;group&nbsp;&nbsp;</span><span style="COLOR: rgb(0,0,0)">=</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">'</span><span style="COLOR: rgb(0,0,0)">(</span><span style="COLOR: rgb(0,0,0)">'</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">&gt;&gt;</span><span style="COLOR: rgb(0,0,0)">&nbsp;exp&nbsp;</span><span style="COLOR: rgb(0,0,0)">&gt;&gt;</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">'</span><span style="COLOR: rgb(0,0,0)">)</span><span style="COLOR: rgb(0,0,0)">'</span><span style="COLOR: rgb(0,0,0)">;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;factor&nbsp;</span><span style="COLOR: rgb(0,0,0)">=</span><span style="COLOR: rgb(0,0,0)">&nbsp;int_p&nbsp;</span><span style="COLOR: rgb(0,0,0)">|</span><span style="COLOR: rgb(0,0,0)">&nbsp;group;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;term&nbsp;&nbsp;&nbsp;</span><span style="COLOR: rgb(0,0,0)">=</span><span style="COLOR: rgb(0,0,0)">&nbsp;factor&nbsp;</span><span style="COLOR: rgb(0,0,0)">&gt;&gt;</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">*</span><span style="COLOR: rgb(0,0,0)">((</span><span style="COLOR: rgb(0,0,0)">'</span><span style="COLOR: rgb(0,0,0)">*</span><span style="COLOR: rgb(0,0,0)">'</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">&gt;&gt;</span><span style="COLOR: rgb(0,0,0)">&nbsp;factor)&nbsp;</span><span style="COLOR: rgb(0,0,0)">|</span><span style="COLOR: rgb(0,0,0)">&nbsp;(</span><span style="COLOR: rgb(0,0,0)">'</span><span style="COLOR: rgb(0,0,0)">/</span><span style="COLOR: rgb(0,0,0)">'</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">&gt;&gt;</span><span style="COLOR: rgb(0,0,0)">&nbsp;factor));<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;exp&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: rgb(0,0,0)">=</span><span style="COLOR: rgb(0,0,0)">&nbsp;term&nbsp;</span><span style="COLOR: rgb(0,0,0)">&gt;&gt;</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">*</span><span style="COLOR: rgb(0,0,0)">((</span><span style="COLOR: rgb(0,0,0)">'</span><span style="COLOR: rgb(0,0,0)">+</span><span style="COLOR: rgb(0,0,0)">'</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">&gt;&gt;</span><span style="COLOR: rgb(0,0,0)">&nbsp;term)&nbsp;</span><span style="COLOR: rgb(0,0,0)">|</span><span style="COLOR: rgb(0,0,0)">&nbsp;(</span><span style="COLOR: rgb(0,0,0)">'</span><span style="COLOR: rgb(0,0,0)">-</span><span style="COLOR: rgb(0,0,0)">'</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">&gt;&gt;</span><span style="COLOR: rgb(0,0,0)">&nbsp;term));<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span></font> </div>
<p><font face="Courier New">这里使用=代替::=, 用&gt;&gt;代替空格连接。并且由于C++语法所限，EBNF中后置的*在spirit中改为前置。<br>等式左边的单词被称为一个rule，等式右边为rule的定义。我们可以看出一个group是一个exp加上一对括号，一个factor是一个整数或者一个group,一个term是一个或多个factor用*/连接，一个exp是一个或多个term用+-连接。处于最顶端的exp可以据此识别出以下表达式<br></font><font face="Courier New"><span class=number>&nbsp;&nbsp;&nbsp;</span> </font></p>
<div style="BORDER-RIGHT: rgb(204,204,204) 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: rgb(204,204,204) 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: rgb(204,204,204) 1px solid; WIDTH: 98%; PADDING-TOP: 4px; BORDER-BOTTOM: rgb(204,204,204) 1px solid; BACKGROUND-COLOR: rgb(238,238,238)"><font face="Courier New">&nbsp;&nbsp;&nbsp;<img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: rgb(0,0,0)">12345</span><span style="COLOR: rgb(0,0,0)"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;</span><span style="COLOR: rgb(0,0,0)">-</span><span style="COLOR: rgb(0,0,0)">12345</span><span style="COLOR: rgb(0,0,0)"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;</span><span style="COLOR: rgb(0,0,0)">+</span><span style="COLOR: rgb(0,0,0)">12345</span><span style="COLOR: rgb(0,0,0)"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;</span><span style="COLOR: rgb(0,0,0)">1</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">+</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">2</span><span style="COLOR: rgb(0,0,0)"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;</span><span style="COLOR: rgb(0,0,0)">1</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">*</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">2</span><span style="COLOR: rgb(0,0,0)"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;</span><span style="COLOR: rgb(0,0,0)">1</span><span style="COLOR: rgb(0,0,0)">/</span><span style="COLOR: rgb(0,0,0)">2</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">+</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">3</span><span style="COLOR: rgb(0,0,0)">/</span><span style="COLOR: rgb(0,0,0)">4</span><span style="COLOR: rgb(0,0,0)"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;</span><span style="COLOR: rgb(0,0,0)">1</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">+</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">2</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">+</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">3</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">+</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">4</span><span style="COLOR: rgb(0,0,0)"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;</span><span style="COLOR: rgb(0,0,0)">1</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">*</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">2</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">*</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">3</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">*</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">4</span><span style="COLOR: rgb(0,0,0)"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;(</span><span style="COLOR: rgb(0,0,0)">1</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">+</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">2</span><span style="COLOR: rgb(0,0,0)">)&nbsp;</span><span style="COLOR: rgb(0,0,0)">*</span><span style="COLOR: rgb(0,0,0)">&nbsp;(</span><span style="COLOR: rgb(0,0,0)">3</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">+</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">4</span><span style="COLOR: rgb(0,0,0)">)<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;(</span><span style="COLOR: rgb(0,0,0)">-</span><span style="COLOR: rgb(0,0,0)">1</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">+</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">2</span><span style="COLOR: rgb(0,0,0)">)&nbsp;</span><span style="COLOR: rgb(0,0,0)">*</span><span style="COLOR: rgb(0,0,0)">&nbsp;(</span><span style="COLOR: rgb(0,0,0)">3</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">+</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">-</span><span style="COLOR: rgb(0,0,0)">4</span><span style="COLOR: rgb(0,0,0)">)<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;</span><span style="COLOR: rgb(0,0,0)">1</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">+</span><span style="COLOR: rgb(0,0,0)">&nbsp;((</span><span style="COLOR: rgb(0,0,0)">6</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">*</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">200</span><span style="COLOR: rgb(0,0,0)">)&nbsp;</span><span style="COLOR: rgb(0,0,0)">-</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">20</span><span style="COLOR: rgb(0,0,0)">)&nbsp;</span><span style="COLOR: rgb(0,0,0)">/</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">6</span><span style="COLOR: rgb(0,0,0)"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;(</span><span style="COLOR: rgb(0,0,0)">1</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">+</span><span style="COLOR: rgb(0,0,0)">&nbsp;(</span><span style="COLOR: rgb(0,0,0)">2</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">+</span><span style="COLOR: rgb(0,0,0)">&nbsp;(</span><span style="COLOR: rgb(0,0,0)">3</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">+</span><span style="COLOR: rgb(0,0,0)">&nbsp;(</span><span style="COLOR: rgb(0,0,0)">4</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">+</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">5</span><span style="COLOR: rgb(0,0,0)">))))<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span></font> </div>
<p><font face="Courier New">&nbsp;&nbsp;&nbsp; 得到一个rule之后，我们就可以用</font> <span class=identifier><font face="Courier New">parse函数对一个串进行识别了。例如<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font> </span></p>
<div style="BORDER-RIGHT: rgb(204,204,204) 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: rgb(204,204,204) 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: rgb(204,204,204) 1px solid; WIDTH: 98%; PADDING-TOP: 4px; BORDER-BOTTOM: rgb(204,204,204) 1px solid; BACKGROUND-COLOR: rgb(238,238,238)"><span style="COLOR: rgb(0,0,0)"><font face="Courier New">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;parse(</font> </span><span style="COLOR: rgb(0,0,0)"><font face="Courier New">"</font> </span><span style="COLOR: rgb(0,0,0)"><font face="Courier New">(1&nbsp;+&nbsp;(2&nbsp;+&nbsp;(3&nbsp;+&nbsp;(4&nbsp;+&nbsp;5))))</font> </span><span style="COLOR: rgb(0,0,0)"><font face="Courier New">"</font> </span><span style="COLOR: rgb(0,0,0)"><font face="Courier New">,&nbsp;exp);</font> </span></div>
<p><font face="Courier New"><br>该函数返回一个结构parse_info，可以通过访问其中的full成员来判断是否成功识别，也可以访问stop成员来获知失败的位置。这里要特别提一点，关于各个符号之间的空格，spirit的文档的正文说的是给parse再传一个参数space_p，通知parse跳过所有的空格，然而在FAQ中又提到，如果使用以上方法定义rule，第三个参数传space_p会失败。原因是使用rule默认定义的规则被称为character level parsing，即字符级别解析，而parse的第3个参数仅适用于phrase level parsing，即语法级别解析。要使用第3个参数可以有几种方法。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1。在parse的第二个参数直接传入一个EBNF表达式，不创建rule对象。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=identifier></span></font> </p>
<div style="BORDER-RIGHT: rgb(204,204,204) 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: rgb(204,204,204) 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: rgb(204,204,204) 1px solid; WIDTH: 98%; PADDING-TOP: 4px; BORDER-BOTTOM: rgb(204,204,204) 1px solid; BACKGROUND-COLOR: rgb(238,238,238)"><span style="COLOR: rgb(0,0,0)"><font face="Courier New">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;parse(</font> </span><span style="COLOR: rgb(0,0,0)"><font face="Courier New">"</font> </span><span style="COLOR: rgb(0,0,0)"><font face="Courier New">hello&nbsp;world</font> </span><span style="COLOR: rgb(0,0,0)"><font face="Courier New">"</font> </span><span style="COLOR: rgb(0,0,0)"><font face="Courier New">,&nbsp;</font> </span><span style="COLOR: rgb(0,0,0)"><font face="Courier New">*</font> </span><span style="COLOR: rgb(0,0,0)"><font face="Courier New">anychar_p,&nbsp;space_p);&nbsp;&nbsp;</font> </span></div>
<p><font face="Courier New"><span class=special><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2。以rule&lt;phrase_scanner_t&gt;创建rule。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span> </font></p>
<div style="BORDER-RIGHT: rgb(204,204,204) 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: rgb(204,204,204) 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: rgb(204,204,204) 1px solid; WIDTH: 98%; PADDING-TOP: 4px; BORDER-BOTTOM: rgb(204,204,204) 1px solid; BACKGROUND-COLOR: rgb(238,238,238)"><span style="COLOR: rgb(0,0,0)"><font face="Courier New">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rule</font> </span><span style="COLOR: rgb(0,0,0)"><font face="Courier New">&lt;</font> </span><span style="COLOR: rgb(0,0,0)"><font face="Courier New">phrase_scanner_t</font> </span><span style="COLOR: rgb(0,0,0)"><font face="Courier New">&gt;</font> </span><span style="COLOR: rgb(0,0,0)"><font face="Courier New">&nbsp;exp;&nbsp;</font> </span></div>
<p><font face="Courier New">注意虽然可以用这两个办法屏蔽空格，但是这样可能完全改变EBNF文法的语义，尤其是在语言本身需要识别空格的时候。对于这种情况，可以不使用第三个参数，并在需要出现空格的地方加上space_p,或者+space_p及*space_p，其中+和*分别表示后面的符号连续出现一次以上和0次以上。例如一个以空格分隔的整数列表可以写成int_p &gt;&gt; *(+space_p &gt;&gt; int_p)<br>&nbsp;&nbsp; 如上使用parse可以识别一个串，但并不能做更多的操作，例如将语法里的各个成分提取出来。对于这样的需求，可以通过actor实现。下面是使用actor的一个简单例子<br>&nbsp;&nbsp;&nbsp;<span class=keyword></span></font> </p>
<div style="BORDER-RIGHT: rgb(204,204,204) 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: rgb(204,204,204) 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: rgb(204,204,204) 1px solid; WIDTH: 98%; PADDING-TOP: 4px; BORDER-BOTTOM: rgb(204,204,204) 1px solid; BACKGROUND-COLOR: rgb(238,238,238)"><font face="Courier New"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;<span style="COLOR: rgb(0,0,255)">bool</span><span style="COLOR: rgb(0,0,0)"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;parse_numbers(</span><span style="COLOR: rgb(0,0,255)">char</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,255)">const</span><span style="COLOR: rgb(0,0,0)">*</span><span style="COLOR: rgb(0,0,0)">&nbsp;str,&nbsp;vector</span><span style="COLOR: rgb(0,0,0)">&lt;</span><span style="COLOR: rgb(0,0,255)">double</span><span style="COLOR: rgb(0,0,0)">&gt;&amp;</span><span style="COLOR: rgb(0,0,0)">&nbsp;v)<br><img id=Codehighlighter1_61_247_Open_Image onclick="this.style.display='none'; Codehighlighter1_61_247_Open_Text.style.display='none'; Codehighlighter1_61_247_Closed_Image.style.display='inline'; Codehighlighter1_61_247_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_61_247_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_61_247_Closed_Text.style.display='none'; Codehighlighter1_61_247_Open_Image.style.display='inline'; Codehighlighter1_61_247_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align=top>&nbsp;&nbsp;&nbsp;</span><span id=Codehighlighter1_61_247_Closed_Text style="BORDER-RIGHT: rgb(128,128,128) 1px solid; BORDER-TOP: rgb(128,128,128) 1px solid; DISPLAY: none; BORDER-LEFT: rgb(128,128,128) 1px solid; BORDER-BOTTOM: rgb(128,128,128) 1px solid; BACKGROUND-COLOR: rgb(255,255,255)"><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_61_247_Open_Text><span style="COLOR: rgb(0,0,0)">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: rgb(0,0,255)">return</span><span style="COLOR: rgb(0,0,0)">&nbsp;parse(str,<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;</span><span style="COLOR: rgb(0,128,0)">//</span><span style="COLOR: rgb(0,128,0)">&nbsp;&nbsp;Begin&nbsp;grammar</span><span style="COLOR: rgb(0,128,0)"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top></span><span style="COLOR: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;real_p[push_back_a(v)]&nbsp;</span><span style="COLOR: rgb(0,0,0)">&gt;&gt;</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">*</span><span style="COLOR: rgb(0,0,0)">(</span><span style="COLOR: rgb(0,0,0)">'</span><span style="COLOR: rgb(0,0,0)">,</span><span style="COLOR: rgb(0,0,0)">'</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">&gt;&gt;</span><span style="COLOR: rgb(0,0,0)">&nbsp;real_p[push_back_a(v)])<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;)<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;,<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: rgb(0,128,0)">//</span><span style="COLOR: rgb(0,128,0)">&nbsp;&nbsp;End&nbsp;grammar</span><span style="COLOR: rgb(0,128,0)"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top></span><span style="COLOR: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;space_p).full;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;}</span></span><span style="COLOR: rgb(0,0,0)"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span></font> </div>
<p><font face="Courier New">注意到<span class=identifier>real_p后面的[]，中括号里面是一个仿函数（函数指针或者函数对象），该仿函数具有如下调用型别<br>&nbsp;&nbsp;&nbsp;</span></font> </p>
<div style="BORDER-RIGHT: rgb(204,204,204) 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: rgb(204,204,204) 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: rgb(204,204,204) 1px solid; WIDTH: 98%; PADDING-TOP: 4px; BORDER-BOTTOM: rgb(204,204,204) 1px solid; BACKGROUND-COLOR: rgb(238,238,238)"><font face="Courier New">&nbsp;&nbsp;&nbsp;<img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: rgb(0,0,255)">void</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,255)">operator</span><span style="COLOR: rgb(0,0,0)">()(IterT&nbsp;first,&nbsp;IterT&nbsp;last)&nbsp;</span><span style="COLOR: rgb(0,0,255)">const</span><span style="COLOR: rgb(0,0,0)">;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;</span><span style="COLOR: rgb(0,0,255)">void</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,255)">operator</span><span style="COLOR: rgb(0,0,0)">()(NumT&nbsp;val)&nbsp;</span><span style="COLOR: rgb(0,0,255)">const</span><span style="COLOR: rgb(0,0,0)">;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;</span><span style="COLOR: rgb(0,0,255)">void</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,255)">operator</span><span style="COLOR: rgb(0,0,0)">()(CharT&nbsp;ch)&nbsp;</span><span style="COLOR: rgb(0,0,255)">const</span><span style="COLOR: rgb(0,0,0)">;</span></font> </div>
<p><span class=special><span class=special><span class=special><font face="Courier New"><br>一旦spase发现了匹配<span class=identifier>real_p的子串，就会调用该functor。不同的rule可能会对应不同的调用型别。</span><br>第一个型别针对一般规则，first和last为两个指向字符的迭代器（一般为char*）,匹配的子串为[first, last)<br>第二个型别针对数字型规则，如real_p和int_p, 参数val是一个数字类型。<br>第三个性别针对单字符型规则，如space_p, 参数ch是一个字符类型。<br><span class=identifier>real_p</span><span class=special>[</span><span class=identifier>push_back_a</span><span class=special>(</span><span class=identifier>v</span><span class=special>)]中的push_back_a是一个spirit已经定义好的functor，它会将匹配好的内容依照匹配到的时间顺序调用v的push_back函数加入到v中。<br><br>&nbsp;&nbsp;&nbsp;到此spirit的常用功能就都介绍完了。要详细深入了解可以参考spirit的文档。<br><br>最后在题一个注意要点。spirit的各种EBNF连接都是指针连接，因此才能在expression被赋值前就在group的定义里面使用。所以在使用EBNF的时候一定要小心不要将局部变量的rule提供给全局或者类成员变量使用，例如：<br>&nbsp;&nbsp;&nbsp;</span></font> </span></span></span></p>
<div style="BORDER-RIGHT: rgb(204,204,204) 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: rgb(204,204,204) 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: rgb(204,204,204) 1px solid; WIDTH: 98%; PADDING-TOP: 4px; BORDER-BOTTOM: rgb(204,204,204) 1px solid; BACKGROUND-COLOR: rgb(238,238,238)"><font face="Courier New">&nbsp;&nbsp;&nbsp;<img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: rgb(0,0,255)">class</span><span style="COLOR: rgb(0,0,0)">&nbsp;A<br><img id=Codehighlighter1_11_166_Open_Image onclick="this.style.display='none'; Codehighlighter1_11_166_Open_Text.style.display='none'; Codehighlighter1_11_166_Closed_Image.style.display='inline'; Codehighlighter1_11_166_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_11_166_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_11_166_Closed_Text.style.display='none'; Codehighlighter1_11_166_Open_Image.style.display='inline'; Codehighlighter1_11_166_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align=top>&nbsp;&nbsp;&nbsp;</span><span id=Codehighlighter1_11_166_Closed_Text style="BORDER-RIGHT: rgb(128,128,128) 1px solid; BORDER-TOP: rgb(128,128,128) 1px solid; DISPLAY: none; BORDER-LEFT: rgb(128,128,128) 1px solid; BORDER-BOTTOM: rgb(128,128,128) 1px solid; BACKGROUND-COLOR: rgb(255,255,255)"><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_11_166_Open_Text><span style="COLOR: rgb(0,0,0)">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rule</span><span style="COLOR: rgb(0,0,0)">&lt;&gt;</span><span style="COLOR: rgb(0,0,0)">&nbsp;s;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;A()<br><img id=Codehighlighter1_45_161_Open_Image onclick="this.style.display='none'; Codehighlighter1_45_161_Open_Text.style.display='none'; Codehighlighter1_45_161_Closed_Image.style.display='inline'; Codehighlighter1_45_161_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_45_161_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_45_161_Closed_Text.style.display='none'; Codehighlighter1_45_161_Open_Image.style.display='inline'; Codehighlighter1_45_161_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span id=Codehighlighter1_45_161_Closed_Text style="BORDER-RIGHT: rgb(128,128,128) 1px solid; BORDER-TOP: rgb(128,128,128) 1px solid; DISPLAY: none; BORDER-LEFT: rgb(128,128,128) 1px solid; BORDER-BOTTOM: rgb(128,128,128) 1px solid; BACKGROUND-COLOR: rgb(255,255,255)"><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_45_161_Open_Text><span style="COLOR: rgb(0,0,0)">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rule</span><span style="COLOR: rgb(0,0,0)">&lt;&gt;</span><span style="COLOR: rgb(0,0,0)">&nbsp;r&nbsp;</span><span style="COLOR: rgb(0,0,0)">=</span><span style="COLOR: rgb(0,0,0)">&nbsp;int_p&nbsp;</span><span style="COLOR: rgb(0,0,0)">|</span><span style="COLOR: rgb(0,0,0)">&nbsp;hex_p;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;s&nbsp;</span><span style="COLOR: rgb(0,0,0)">=</span><span style="COLOR: rgb(0,0,0)">&nbsp;r&nbsp;</span><span style="COLOR: rgb(0,0,0)">&gt;&gt;</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">*</span><span style="COLOR: rgb(0,0,0)">(</span><span style="COLOR: rgb(0,0,0)">+</span><span style="COLOR: rgb(0,0,0)">space_p&nbsp;</span><span style="COLOR: rgb(0,0,0)">&gt;&gt;</span><span style="COLOR: rgb(0,0,0)">&nbsp;r);&nbsp;</span><span style="COLOR: rgb(0,128,0)">//</span><span style="COLOR: rgb(0,128,0)">error,&nbsp;r&nbsp;destructed&nbsp;after&nbsp;return&nbsp;</span><span style="COLOR: rgb(0,128,0)"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top></span><span style="COLOR: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="COLOR: rgb(0,0,0)"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;}</span></span><span style="COLOR: rgb(0,0,0)">;<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></font> </div>
<p><span class=special><span class=identifier><font face="Courier New"><span class=special><span class=identifier><span class=special><span class=special><span class=special><span class=special>如果真想使用局部作用域，可以在局部的rule前面加上static.</span> </span></span></span></span></span></font></span></span></p>
<img src ="http://www.cppblog.com/shifan3/aggbug/1857.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/shifan3/" target="_blank">shifan3</a> 2005-12-18 12:02 <a href="http://www.cppblog.com/shifan3/archive/2005/12/18/1857.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>