﻿<?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