<?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++博客-cuigang-文章分类-《C++设计新思维》读书笔记</title><link>http://www.cppblog.com/cuigang/category/5814.html</link><description /><language>zh-cn</language><lastBuildDate>Sat, 12 Jan 2008 15:57:11 GMT</lastBuildDate><pubDate>Sat, 12 Jan 2008 15:57:11 GMT</pubDate><ttl>60</ttl><item><title>《C++设计新思维》读书笔记（23）</title><link>http://www.cppblog.com/cuigang/articles/41045.html</link><dc:creator>cuigang</dc:creator><author>cuigang</author><pubDate>Sat, 12 Jan 2008 12:29:00 GMT</pubDate><guid>http://www.cppblog.com/cuigang/articles/41045.html</guid><wfw:comment>http://www.cppblog.com/cuigang/comments/41045.html</wfw:comment><comments>http://www.cppblog.com/cuigang/articles/41045.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/cuigang/comments/commentRss/41045.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/cuigang/services/trackbacks/41045.html</trackback:ping><description><![CDATA[<div class="Section1" style="font-family: courier new;">
<p><font size="2">4.4
Chunks</font><font size="2">（大块内存）</font></p>
<p><font size="2">每个</font><font size="2">Chunk</font><font size="2">对象包含并管理一大块内存，其中包含固定数量的区块。你可以在构造期间设定区块的大小和数量。你可以从</font><font size="2">chunk</font><font size="2">中分配和归还区块。一旦</font><font size="2">chunk</font><font size="2">之中没有剩余区块，分配函数便传回</font><font size="2">0</font><font size="2">。</font><font size="2">chunk</font><font size="2">定义如下：</font></p>
<p><font color="green" size="2">
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><font>//</font><font>&nbsp;Nothing&nbsp;is&nbsp;private&nbsp;-&nbsp;Chunk&nbsp;is&nbsp;a&nbsp;Plain&nbsp;Old&nbsp;Data&nbsp;(POD)&nbsp;structure<br></font><font>//</font><font>&nbsp;structure&nbsp;defined&nbsp;inside&nbsp;FixedAllocator<br></font><font>//</font><font>&nbsp;and&nbsp;manipulated&nbsp;only&nbsp;by&nbsp;it</font><font><br></font><font>struct</font><font>&nbsp;Chunk{<br>&nbsp;&nbsp;&nbsp;&nbsp;</font><font>void</font><font>&nbsp;Init(std::size_t&nbsp;blockSize,&nbsp;unsigned&nbsp;</font><font>char</font><font>&nbsp;blocks);<br>&nbsp;&nbsp;&nbsp;&nbsp;</font><font>void</font><font>&nbsp;Release();<br>&nbsp;&nbsp;&nbsp;&nbsp;</font><font>void</font><font>*</font><font>&nbsp;Allocate(std::size_t&nbsp;blockSize);<br>&nbsp;&nbsp;&nbsp;&nbsp;</font><font>void</font><font>&nbsp;Deallocate(</font><font>void</font><font>*</font><font>&nbsp;p,&nbsp;std::size_t&nbsp;blockSize);<br>&nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;</font><font>char</font><font>*</font><font>&nbsp;pData_;<br>&nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;</font><font>char</font><font><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;firstAvailableBlock_,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;blocksAvailable_;<br>};</font></div>
<br>
</font></p>
<p><font size="2">除了一个指针指向被管理内存本身，</font><font size="2">firstAvailableBlock_</font><font size="2">保存</font><font size="2">chunk</font><font size="2">内第一个可用区块的索引，</font><font size="2">blocksAvailable_</font><font size="2">保存</font><font size="2">chunk</font><font size="2">内可用区块总数。</font></p>
<p><font size="2">Chunk</font><font size="2">的接口非常简单。</font><font size="2">Init()</font><font size="2">用于初始化，</font><font size="2">Release()</font><font size="2">用来释放。</font><font size="2">Allocate()</font><font size="2">用来分配，</font><font size="2">Deallocate()</font><font size="2">用来归还。</font><font size="2">Chunk</font><font size="2">不保存区块的大小，它没有构造函数、析构函数和赋值运算符，定义自己的</font><font size="2">copy</font><font size="2">语义会损及上一层的效率</font><font size="2">——</font><font size="2">上一层将</font><font size="2">chunk</font><font size="2">置于一个</font><font size="2">vector</font><font size="2">。</font></p>
<p><font size="2">chunk</font><font size="2">的结构反应出设计中一个重要折衷。</font><font size="2">blocksAvailable_</font><font size="2">和</font><font size="2">firstAvailableBlock_</font><font size="2">都是</font><font size="2">unsigned char</font><font size="2">型别，因此一个</font><font size="2">chunk</font><font size="2">无法拥有</font><font size="2">255</font><font size="2">个以上的区块。</font></p>
<p><font size="2">另外我们利用</font><font size="2">&#8220;</font><font size="2">未被使用的区块</font><font size="2">&#8221;</font><font size="2">的第一个</font><font size="2">bytes</font><font size="2">来存放下一个</font><font size="2">&#8220;</font><font size="2">未被使用的区块</font><font size="2">&#8221;</font><font size="2">的索引号。这样我们就拥有了一个单向链表。无需占用内存。</font></p>
<p><font size="2">初始化函数如下：</font></p>
<p><font color="green" size="2">
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><font>void</font><font>&nbsp;Chunk::Init(std::size_t&nbsp;blockSize,&nbsp;unsigned&nbsp;</font><font>char</font><font>&nbsp;blocks){<br>&nbsp;&nbsp;&nbsp;&nbsp;pData_&nbsp;</font><font>=</font><font>&nbsp;</font><font>new</font><font>&nbsp;unsigned&nbsp;</font><font>char</font><font>[blockSize&nbsp;</font><font>*</font><font>&nbsp;blocks];<br>&nbsp;&nbsp;&nbsp;&nbsp;firstAvailableBlock_&nbsp;</font><font>=</font><font>&nbsp;</font><font>0</font><font>;<br>&nbsp;&nbsp;&nbsp;&nbsp;blocksAvailable_&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font>=</font><font>&nbsp;blcoks;<br>&nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;</font><font>char</font><font>&nbsp;i&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font>=</font><font>&nbsp;</font><font>0</font><font>;<br>&nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;</font><font>char</font><font>*</font><font>&nbsp;p&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font>=</font><font>&nbsp;pData_;<br>&nbsp;&nbsp;&nbsp;&nbsp;</font><font>for</font><font>(;&nbsp;i&nbsp;</font><font>!=</font><font>&nbsp;blocks;&nbsp;p&nbsp;</font><font>+=</font><font>&nbsp;blockSize){<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font>*</font><font>p&nbsp;</font><font>=</font><font>&nbsp;</font><font>++</font><font>i;<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br>}</font></div>
<br>
</font></p>
<p><font size="2">我们来看一下将区块数量限制在</font><font size="2">unsigned char</font><font size="2">的大小（</font><font size="2">0~255</font><font size="2">）的原因。假如我们使用一个较大型别，比如</font><font size="2">unsigned short</font><font size="2">（</font><font size="2">0~65535</font><font size="2">），我们将遭遇两个问题，一个小问题，一个大问题。</font></p>
<p><font size="2">小问题是我们无法分配小于</font><font size="2">sizeof(unsigned
short)</font><font size="2">的区块，这令人尴尬，因为我们正在建立一个小型对象分配器。（这里指的是，对于</font><font size="2">1 byte</font><font size="2">区块大小的</font><font size="2">chunk</font><font size="2">，由于索引号有</font><font size="2">2 bytes</font><font size="2">，无法建立内嵌的单向链表，</font><font size="2">cuigang</font><font size="2">）。</font></p>
<p><font size="2">大问题是齐位（</font><font size="2">alignment</font><font size="2">）问题。假设你为一个</font><font size="2">5 bytes</font><font size="2">区块建立一个专属分配器。这种情况下如果想将</font><font size="2">&#8220;</font><font size="2">指向如此一个</font><font size="2">5 bytes</font><font size="2">区块</font><font size="2">&#8221;</font><font size="2">的指针转换为</font><font size="2">unsigned int</font><font size="2">（原文如此，估计作者是想说从一个起始为奇地址的区块提领（</font><font size="2">dereference</font><font size="2">）一个偶字节变量会导致异常的问题，这几个函数中都有提领的动作。</font><font size="2">cuigang</font><font size="2">），会造成不确定行为。</font></p>
<p><font size="2">unsigned
char</font><font size="2">类型可以简单的解决这个问题。它大小为</font><font size="2">1</font><font size="2">，无齐位问题。只不过我们将无法分配多于</font><font size="2">255</font><font size="2">的区块。但这个我们是可以接受的。</font></p>
<p><font size="2">分配函数</font><font size="2">Allocate()</font><font size="2">是典型的</font><font size="2">list</font><font size="2">操作。</font></p>
<p><font color="green" size="2">
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><font>void</font><font>*</font><font>&nbsp;Chunk::Allocate(std::size_t&nbsp;blockSize){<br>&nbsp;&nbsp;&nbsp;&nbsp;</font><font>if</font><font>(</font><font>!</font><font>blocksAvailable_)&nbsp;</font><font>return</font><font>&nbsp;</font><font>0</font><font>;<br>&nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;</font><font>char</font><font>*</font><font>&nbsp;pResult&nbsp;</font><font>=</font><font><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pData_&nbsp;</font><font>+</font><font>&nbsp;(firstAvailableBlock_&nbsp;</font><font>*</font><font>&nbsp;blockSize);<br>&nbsp;&nbsp;&nbsp;&nbsp;firstAvailableBlock_&nbsp;</font><font>=</font><font>&nbsp;</font><font>*</font><font>pResult;<br>&nbsp;&nbsp;&nbsp;&nbsp;</font><font>--</font><font>blocksAvailable_;<br>&nbsp;&nbsp;&nbsp;&nbsp;</font><font>return</font><font>&nbsp;pResult;<br>};</font></div>
<br>
</font></p>
<p><font size="2">这个函数成本很小，不需要查找动作，在常数事件内完成，而不像系统分配需要线性时间。</font></p>
<p><font size="2">归还函数</font><font size="2">Deallocate()</font><font size="2">行为相反，这里要注意，由于</font><font size="2">Chunk</font><font size="2">对区块大小一无所知，所以你必须将区块大小当作参数传入，同时注意里面很多的异常处理来避免你将错误指针传入：</font></p>
<p><font color="green" size="2">
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><font>void</font><font>&nbsp;Chunk::Deallocate(</font><font>void</font><font>*</font><font>&nbsp;p,&nbsp;std::size_t&nbsp;blockSize){<br>&nbsp;&nbsp;&nbsp;&nbsp;assert(p&nbsp;</font><font>&gt;=</font><font>&nbsp;pData_);<br>&nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;</font><font>char</font><font>*</font><font>&nbsp;toRelease&nbsp;</font><font>=</font><font>&nbsp;static_cast</font><font>&lt;</font><font>unsigned&nbsp;</font><font>char</font><font>*&gt;</font><font>(p);<br>&nbsp;&nbsp;&nbsp;&nbsp;assert((toRelease&nbsp;</font><font>-</font><font>&nbsp;pData_)&nbsp;</font><font>%</font><font>&nbsp;blockSize&nbsp;</font><font>==</font><font>&nbsp;</font><font>0</font><font>);<br>&nbsp;&nbsp;&nbsp;&nbsp;</font><font>*</font><font>toRelease&nbsp;</font><font>=</font><font>&nbsp;firstAvailableBlock_;<br>&nbsp;&nbsp;&nbsp;&nbsp;firstAvailableBlcok_&nbsp;</font><font>=</font><font>&nbsp;static_cast</font><font>&lt;</font><font>unsigned&nbsp;</font><font>char</font><font>&gt;</font><font>(<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(toRelease&nbsp;</font><font>-</font><font>&nbsp;pData_)&nbsp;</font><font>/</font><font>&nbsp;blockSize);<br>&nbsp;&nbsp;&nbsp;&nbsp;assert(firstAvailableBlock&nbsp;</font><font>==</font><font>&nbsp;(toRelease&nbsp;</font><font>-</font><font>&nbsp;pData_)&nbsp;</font><font>/</font><font>&nbsp;blockSize);<br>&nbsp;&nbsp;&nbsp;&nbsp;</font><font>++</font><font>blocksAvailable_;<br>};</font></div>
<br>
</font></p>
</div>
<br><img src ="http://www.cppblog.com/cuigang/aggbug/41045.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cuigang/" target="_blank">cuigang</a> 2008-01-12 20:29 <a href="http://www.cppblog.com/cuigang/articles/41045.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>《C++设计新思维》读书笔记（22）</title><link>http://www.cppblog.com/cuigang/articles/40933.html</link><dc:creator>cuigang</dc:creator><author>cuigang</author><pubDate>Thu, 10 Jan 2008 15:00:00 GMT</pubDate><guid>http://www.cppblog.com/cuigang/articles/40933.html</guid><wfw:comment>http://www.cppblog.com/cuigang/comments/40933.html</wfw:comment><comments>http://www.cppblog.com/cuigang/articles/40933.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/cuigang/comments/commentRss/40933.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/cuigang/services/trackbacks/40933.html</trackback:ping><description><![CDATA[<p><font face="Courier new" size="2">4.2
</font><font face="宋体" size="2">内存分配器的工作方式</font><font face="宋体" size="2"></font></p>
<p><font face="宋体" size="2">（本节内容可以参考操作系统书籍，</font><font face="Courier new" size="2">cuigang</font><font face="宋体" size="2">）</font><font face="宋体" size="2"></font></p>
<p><font face="宋体" size="2">内存分配器如何工作？它管理一个由</font><font face="Courier new" size="2">raw bytes</font><font face="宋体" size="2">所组成的内存池。薄记结构可以简单如下：</font><font face="宋体" size="2"></font></p>
<p><font color="green" face="Courier new" size="2">
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #0000ff;"><font>struct</font></span><span style="color: #000000;"><font>&nbsp;MemControlBlock{<br>&nbsp;&nbsp;&nbsp;&nbsp;std::size_t&nbsp;&nbsp;size_;<br>&nbsp;&nbsp;&nbsp;&nbsp;</font></span><span style="color: #0000ff;"><font>bool</font></span><span style="color: #000000;"><font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;available_;<br>};</font></span></div>
<br></font></p>
<p><font face="Courier new" size="2">MemControlBlock</font><font face="宋体" size="2">对象管理的内存紧随其后，大小</font><font face="Courier new" size="2"> size_</font><font face="宋体" size="2">，然后是另一个控制块。初始时，内存池中只有一个</font><font face="Courier new" size="2">MemControlBlock</font><font face="宋体" size="2">，并将所有内存视为一大块，这就是所谓</font><font face="Courier new" size="2">root</font><font face="宋体" size="2">控制块，永不离开最初位置。以</font>
</p>
<p><font color="green" face="Courier new" size="2">+===================+=================+==================+<br>
| available_ : ture | size_ : 1048571 |&nbsp;&nbsp; mem[1048571]&nbsp;&nbsp; |<br>
+===================+=================+==================+<br>
|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
|<br>
|-----&gt; 1 byte &lt;----|----&gt; 4 bytes &lt;--|-&gt; 1048571bytes &lt;-|<br>
|-----------------------&gt; 1048576 bytes &lt;----------------|</font><font face="宋体" size="2"></font></p>
<p><font face="宋体" size="2">每次分配都引发一次线性查找，找到一个合适区块，适合策略有最先匹配法则（</font><font face="Courier new" size="2">first fit</font><font face="宋体" size="2">）、最佳匹配（</font><font face="Courier new" size="2">best
fit</font><font face="宋体" size="2">），最差匹配（</font><font face="Courier new" size="2">worst fit</font><font face="宋体" size="2">），甚至随机匹配（</font><font face="Courier new" size="2">random fit</font><font face="宋体" size="2">）。有趣的是最差匹配比最佳匹配好！</font><font face="宋体" size="2"></font></p>
<p><font face="宋体" size="2">每次归还区块，同样需要一次线性搜索，找出待归还区块的前一区块并调整大小。</font><font face="宋体" size="2"></font></p>
<p><font face="宋体" size="2">如你所看，这一策略时间上并非高效。但空间上开销较小，甚至我们可以再调整：</font><font face="宋体" size="2"></font></p>
<p>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #008000;">//</span><span style="color: #008000;">注意下面代码依赖编译器和平台</span><span style="color: #008000;"><br></span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;MemControlBlock{<br>&nbsp;&nbsp;&nbsp;&nbsp;std::size_t&nbsp;&nbsp;size_&nbsp;:&nbsp;</span><span style="color: #000000;">31</span><span style="color: #000000;">;<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">bool</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;available_&nbsp;:&nbsp;</span><span style="color: #000000;">1</span><span style="color: #000000;">;<br>};</span></div>
<br><font color="green" face="Courier new" size="2"></font></p>
<p><font face="宋体" size="2">为了前序遍历，我们可以定义为双向链表：</font><font face="宋体" size="2"></font></p>
<p><font color="green" face="Courier new" size="2">
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #0000ff;"><font>struct</font></span><span style="color: #000000;"><font>&nbsp;MemControlBlock{<br>&nbsp;&nbsp;&nbsp;&nbsp;</font></span><span style="color: #0000ff;"><font>bool</font></span><span style="color: #000000;"><font>&nbsp;available_;<br>&nbsp;&nbsp;&nbsp;&nbsp;MemControlBlock</font></span><span style="color: #000000;"><font>*</font></span><span style="color: #000000;"><font>&nbsp;next_;<br>&nbsp;&nbsp;&nbsp;&nbsp;MemControlBlock</font></span><span style="color: #000000;"><font>*</font></span><span style="color: #000000;"><font>&nbsp;prev_;<br>};</font></span></div>
<br></font></p>
<p><font face="宋体" size="2">这里我们不需要</font><font face="Courier new" size="2">size_</font><font face="宋体" size="2">了，我们可以通过</font><font face="Courier new" size="2">this-&gt;next - this </font><font face="宋体" size="2">来得到。</font><font face="宋体" size="2"></font></p>
<p><font face="宋体" size="2">尽管如此，分配动作还是得消耗线性时间。要减轻这样的消耗，有如多巧妙技术可用，但都各有利弊，存在某种情况下的不良性能（参考</font><font face="Courier new" size="2">Knuth</font><font face="宋体" size="2">著作）。这里我们不对其讨论，我们的焦点是可最佳处理小型对象的</font><font face="Courier new" size="2">&#8220;</font><font face="宋体" size="2">专用分配器</font><font face="Courier new" size="2">&#8221;</font><font face="宋体" size="2">。</font><font face="宋体" size="2"></font></p>
<p><font face="Courier new" size="2">4.3
</font><font face="宋体" size="2">小型对象分配器</font><font face="宋体" size="2"></font></p>
<p><font face="宋体" size="2">本章介绍的小型对象分配器分为</font><font face="Courier new" size="2">4</font><font face="宋体" size="2">层结构。如图所示，下层提供功能供上层使用。</font><font face="宋体" size="2"></font></p>
<p><font color="green" face="Courier new" size="2">+-------------------+<br>
|&nbsp;&nbsp;&nbsp; SmallObject&nbsp;&nbsp;&nbsp; |<br>
+-------------------+<br>
| SmallObjAllocator |<br>
+-------------------+<br>
|&nbsp;&nbsp; FixedAllocator&nbsp; |<br>
+-------------------+<br>
|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Chunk&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
|<br>
+-------------------+</font><font face="宋体" size="2"></font></p>
<p><font face="宋体" size="2">最下层是</font><font face="Courier new" size="2">Chunk</font><font face="宋体" size="2">对象，每一个</font><font face="Courier new" size="2">Chunk</font><font face="宋体" size="2">管理一大块内存，此大块内存包含整数个固定大小的区块。可以用来分配和归还，当其中没有剩余时，分配失败返回零。</font><font face="宋体" size="2"></font></p>
<p><font face="宋体" size="2">第二层是</font><font face="Courier new" size="2">FixAllocator
class</font><font face="宋体" size="2">，其以</font><font face="Courier new" size="2">Chunk</font><font face="宋体" size="2">为构件。主要用来满足那些</font><font face="Courier new" size="2">&#8220;</font><font face="宋体" size="2">累计总量超过</font><font face="Courier new" size="2">Chunk</font><font face="宋体" size="2">容量</font><font face="Courier new" size="2">&#8221;</font><font face="宋体" size="2">的请求。</font><font face="Courier new" size="2">FixAllocator</font><font face="宋体" size="2">通过一个</font><font face="Courier new" size="2">array</font><font face="宋体" size="2">（实际是</font><font face="Courier new" size="2">vector</font><font face="宋体" size="2">）组合</font><font face="Courier new" size="2">Chunks</font><font face="宋体" size="2">。如果所有</font><font face="Courier new" size="2">Chunk</font><font face="宋体" size="2">都被使用，</font><font face="Courier new" size="2">FixAllocator</font><font face="宋体" size="2">分配新</font><font face="Courier new" size="2">Chunk</font><font face="宋体" size="2">，并加入</font><font face="Courier new" size="2">array</font><font face="宋体" size="2">，来满足需求。</font><font face="宋体" size="2"></font></p>
<p><font face="宋体" size="2">第三层是</font><font face="Courier new" size="2">SmallObjectAllocator</font><font face="宋体" size="2">提供通用分配</font><font face="Courier new" size="2">/</font><font face="宋体" size="2">归还函数。拥有数个</font><font face="Courier new" size="2">FixedAllocator</font><font face="宋体" size="2">对象，每个负责分配某特定大小对象。根据申请</font><font face="Courier new" size="2">bytes</font><font face="宋体" size="2">个数不同，</font><font face="Courier new" size="2">SmallObjAllocator</font><font face="宋体" size="2">对象会将内存分配申请分发。如果请求量过大，会转交系统</font><font face="Courier new" size="2">new</font><font face="宋体" size="2">。</font><font face="宋体" size="2"></font></p>
<font face="宋体" size="2">第四层是</font><font face="Courier new" size="2">SmallObject</font><font face="宋体" size="2">，它包装</font><font face="Courier new" size="2">FixedAllocator</font><font face="宋体" size="2">，以便向</font><font face="Courier new" size="2">C++
classes</font><font face="宋体" size="2">提供封装良好的分配服务。</font><font face="Courier new" size="2">SmallObject</font><font face="宋体" size="2">重载</font><font face="Courier new" size="2">new</font><font face="宋体" size="2">和</font><font face="Courier new" size="2">delete</font><font face="宋体" size="2">。你只需要让你的对象派生于</font><font face="Courier new" size="2">SmallObject</font><font face="宋体" size="2">。</font>
<br><img src ="http://www.cppblog.com/cuigang/aggbug/40933.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cuigang/" target="_blank">cuigang</a> 2008-01-10 23:00 <a href="http://www.cppblog.com/cuigang/articles/40933.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>《C++设计新思维》读书笔记（21）</title><link>http://www.cppblog.com/cuigang/articles/40932.html</link><dc:creator>cuigang</dc:creator><author>cuigang</author><pubDate>Thu, 10 Jan 2008 14:54:00 GMT</pubDate><guid>http://www.cppblog.com/cuigang/articles/40932.html</guid><wfw:comment>http://www.cppblog.com/cuigang/comments/40932.html</wfw:comment><comments>http://www.cppblog.com/cuigang/articles/40932.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/cuigang/comments/commentRss/40932.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/cuigang/services/trackbacks/40932.html</trackback:ping><description><![CDATA[<p><font face="Courier new" size="2"></font></p>
<span style="font-size: 10pt;">
<p><font face="Courier new" size="2">3.13
</font><font face="宋体" size="2">运用</font><font face="Courier new" size="2">typelist</font><font face="宋体" size="2">自动产生</font><font face="Courier new" size="2">classes</font><font face="宋体" size="2">（不好意思，没太看懂，略去）</font><font face="宋体" size="2"></font></p>
<p><font face="Courier new" size="2">4
</font><font face="宋体" size="2">小型对象分配技术</font><font face="宋体" size="2"></font></p>
<p><font face="Courier new" size="2">4.1
</font><font face="宋体" size="2">缺省的</font><font face="Courier new" size="2">Free Store</font><font face="宋体" size="2">分配器</font><font face="宋体" size="2"></font></p>
<p><font face="宋体" size="2">由于某些</font><font face="Courier new" size="2">&#8220;</font><font face="宋体" size="2">神秘原因</font><font face="Courier new" size="2">&#8221;</font><font face="宋体" size="2">，系统缺省的</font><font face="Courier new" size="2">free store</font><font face="宋体" size="2">分配器速度极慢，恶名昭彰。其中一个可能的原因是，它通常只是</font><font face="Courier new" size="2">C heap</font><font face="宋体" size="2">分配器（</font><font face="Courier new" size="2">malloc/realloc/free</font><font face="宋体" size="2">）的浅层包装。</font><font face="Courier new" size="2">C heap</font><font face="宋体" size="2">分配器并未特别针对小块内存的分配进行优化。</font><font face="Courier new" size="2">C</font><font face="宋体" size="2">程序通常十分有条理地、保守地使用内存，却不会采用任何</font><font face="Courier new" size="2">&#8220;</font><font face="宋体" size="2">导致小块内存被大量分配</font><font face="Courier new" size="2">&#8221;</font><font face="宋体" size="2">的手法或技巧。</font><font face="Courier new" size="2">C</font><font face="宋体" size="2">程序通常分配中大型对象（数百或者数千个</font><font face="Courier new" size="2">bytes</font><font face="宋体" size="2">）。</font><font face="宋体" size="2"></font></p>
<p><font face="宋体" size="2">除了速度慢，</font><font face="Courier new" size="2">C++</font><font face="宋体" size="2">缺省分配器的通用性也造成小型对象空间分配的低效。（细述，指对小对象会额外分配空间，以保证不小于最小区块，而且链表的薄记管理部分也开销很大，对小对象比较多时尤为明显）。</font><font face="宋体" size="2"></font></p>
<p><font face="宋体" size="2">在</font><font face="Courier new" size="2">C++</font><font face="宋体" size="2">中，动态分配很重要。执行期多态性和动态分配的联系最为密切。</font><font face="Courier new" size="2">&#8220;Pimpl</font><font face="宋体" size="2">手法</font><font face="Courier new" size="2">&#8221;</font><font face="宋体" size="2">就要求</font><font face="Courier new" size="2">&#8220;</font><font face="宋体" size="2">以</font><font face="Courier new" size="2">free store</font><font face="宋体" size="2">分配取代</font><font face="Courier new" size="2">stack</font><font face="宋体" size="2">分配</font><font face="Courier new" size="2">&#8221;</font><font face="宋体" size="2">为前提。</font><font face="宋体" size="2"></font></p>
<font face="宋体" size="2">因此，在迈向高效</font><font face="Courier new" size="2">C++</font><font face="宋体" size="2">程序开发的道路上，缺省分配器的低劣性能成为一种障碍。老练的</font><font face="Courier new" size="2">C++</font><font face="宋体" size="2">程序员会尽量避免使用</font><font face="Courier new" size="2">&#8220;</font><font face="宋体" size="2">采行</font><font face="Courier new" size="2">free store</font><font face="宋体" size="2">分配行为</font><font face="Courier new" size="2">&#8221;</font><font face="宋体" size="2">的语言构件，因为根据经验他们知道它的成本高昂。缺省分配器不仅是个具体问题，还可能成为一个心理障碍。</font>
</span><br><img src ="http://www.cppblog.com/cuigang/aggbug/40932.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cuigang/" target="_blank">cuigang</a> 2008-01-10 22:54 <a href="http://www.cppblog.com/cuigang/articles/40932.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>《C++设计新思维》读书笔记（20）</title><link>http://www.cppblog.com/cuigang/articles/40931.html</link><dc:creator>cuigang</dc:creator><author>cuigang</author><pubDate>Thu, 10 Jan 2008 14:49:00 GMT</pubDate><guid>http://www.cppblog.com/cuigang/articles/40931.html</guid><wfw:comment>http://www.cppblog.com/cuigang/comments/40931.html</wfw:comment><comments>http://www.cppblog.com/cuigang/articles/40931.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/cuigang/comments/commentRss/40931.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/cuigang/services/trackbacks/40931.html</trackback:ping><description><![CDATA[<span style="font-size: 10pt;"><span style="font-family: courier new;"></span><span style="font-family: courier new;">3.9 移除typelist中的某个元素</span><br style="font-family: courier new;"><br style="font-family: courier new;"><span style="font-family: courier new;">移除第一个匹配者：</span><br style="font-family: courier new;"><br style="font-family: courier new;">
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%; font-family: courier new;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #000000;">template&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;TList,&nbsp;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;T</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;Erase;<br>template&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;T</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;Erase</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">NullType,&nbsp;T</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">{<br>&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;NullType&nbsp;Result;<br>};<br>template</span><span style="color: #000000;">&lt;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;T,&nbsp;calss&nbsp;Tail</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br></span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;Erase</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">Typelist</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">T,&nbsp;Tail</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;T</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">{<br>&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;Tail&nbsp;Result;<br>};<br>template&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;Head,&nbsp;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;Tail,&nbsp;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;T</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br></span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;Erase</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">Typelist</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">Head,&nbsp;Tail</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">,&nbsp;T</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">{<br>&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;Typelist</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">Head,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typename&nbsp;Erase</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">Tail,&nbsp;T</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">::Result</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Result;<br>};</span></div>
<br style="font-family: courier new;"><br style="font-family: courier new;"><span style="font-family: courier new;">注意Erase&lt;double, int&gt;这样使用会导致编译错误。移除所有匹配者的实现如下：</span><br style="font-family: courier new;"><br style="font-family: courier new;">
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%; font-family: courier new;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #000000;">template&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;Tlist,&nbsp;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;T</span><span style="color: #000000;">&gt;</span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;EraseAll;<br>template&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;T</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;EraseAll</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">NullType,&nbsp;T</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">{<br>&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;NullType&nbsp;Result;<br>};<br>template&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;T,&nbsp;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;Tail</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br></span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;EraseAll</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">Typelist</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">T,&nbsp;Tail</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">,&nbsp;T</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">{<br>&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;typname&nbsp;EraseAll</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">Tail,&nbsp;T</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">::Result&nbsp;Result;<br>};<br>template&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;Head,&nbsp;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;Tail,&nbsp;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;T</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br></span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;EraseAll</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">Typelist</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">Head,&nbsp;Tail</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">,&nbsp;T</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">{<br>&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;Typelist</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">Head,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typename&nbsp;EraseAll</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">Tail,&nbsp;T</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">::Result</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Result;<br>};</span></div>
<br style="font-family: courier new;"><br style="font-family: courier new;"><span style="font-family: courier new;">3.10 移除重复元素（略）</span><br style="font-family: courier new;"><span style="font-family: courier new;">3.11 取代Typelist中的某个元素（略）</span><br style="font-family: courier new;"><span style="font-family: courier new;">3.12 为Typelists局部更换次序（略） </span><br><br></span><img src ="http://www.cppblog.com/cuigang/aggbug/40931.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cuigang/" target="_blank">cuigang</a> 2008-01-10 22:49 <a href="http://www.cppblog.com/cuigang/articles/40931.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>《C++设计新思维》读书笔记（19）</title><link>http://www.cppblog.com/cuigang/articles/40446.html</link><dc:creator>cuigang</dc:creator><author>cuigang</author><pubDate>Sat, 05 Jan 2008 04:19:00 GMT</pubDate><guid>http://www.cppblog.com/cuigang/articles/40446.html</guid><wfw:comment>http://www.cppblog.com/cuigang/comments/40446.html</wfw:comment><comments>http://www.cppblog.com/cuigang/articles/40446.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/cuigang/comments/commentRss/40446.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/cuigang/services/trackbacks/40446.html</trackback:ping><description><![CDATA[<span style="font-size: 8pt;"><span style="font-family: courier new;"></span><span style="font-family: courier new;"></span><br style="font-family: courier new;"><span style="font-family: courier new;">3.6 索引式访问</span><span style="font-family: courier new;"></span><br style="font-family: courier new;"><br style="font-family: courier new;"><span style="font-family: courier new;">索引式访问使typelist访问线性化。象在static世界中一样，索引必须是编译期常数。一个带有索引的template声明如下：</span><span style="font-family: courier new;"></span><br style="font-family: courier new;"><br style="font-family: courier new;"><span style="font-family: courier new;">
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #000000;">template&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;TList,&nbsp;unsigned&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;index&nbsp;</span><span style="color: #000000;">&gt;</span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;TypeAt;</span></div>
</span><span style="font-family: courier new;"></span><br style="font-family: courier new;"><br style="font-family: courier new;"><span style="font-family: courier new;">实现如下：</span><span style="font-family: courier new;"></span><br style="font-family: courier new;"><br style="font-family: courier new;"><span style="font-family: courier new;">
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #000000;">template&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;Head,&nbsp;Class&nbsp;Tail</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br></span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;TypeAt</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">Typelist</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">Head,&nbsp;Tail</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">,&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">{<br>&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;Head&nbsp;Result;<br>};<br>template&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;Head,&nbsp;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;Tail,&nbsp;unsigned&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;i</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br></span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;TypeAt</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">Typelist</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">Head,&nbsp;Tail</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">,&nbsp;i</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">{<br>&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;typename&nbsp;TypeAt</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">Tail,&nbsp;i</span><span style="color: #000000;">-</span><span style="color: #000000;">1</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">::Result&nbsp;Result;<br>};<br></span></div>
</span><br style="font-family: courier new;"><span style="font-family: courier new;">如果你试着越界访问，会编译出错。对Typelist进行索引访问，花费的时间和typelist大小有关，但这个时间全部花在编译期。</span><br style="font-family: courier new;"><span style="font-family: courier new;"></span><br style="font-family: courier new;"><span style="font-family: courier new;">3.7 查找Typelist</span><span style="font-family: courier new;"></span><br style="font-family: courier new;"><br style="font-family: courier new;"><span style="font-family: courier new;">我们用IndexOf来查找Typelist中一个型别，返回其位置，找不到返回-1。</span><span style="font-family: courier new;"></span><br style="font-family: courier new;"><br style="font-family: courier new;"><span style="font-family: courier new;">
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #000000;">template&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;TList,&nbsp;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;T</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;IndexOf;<br>template&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;T</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br></span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;IndexOf</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">NullType,&nbsp;T</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">{<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">enum</span><span style="color: #000000;">{value&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">-</span><span style="color: #000000;">1</span><span style="color: #000000;">};<br>};<br>template&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;Tail,&nbsp;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;T</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br></span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;IndexOf</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">Typelist</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">T,&nbsp;Tail</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">,&nbsp;T</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">{<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">enum</span><span style="color: #000000;">{value&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">;}<br>};<br>template&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;Head,&nbsp;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;Tail,&nbsp;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;T</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br></span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;IndexOf</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">Typelist</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">Head,&nbsp;Tail</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">,&nbsp;T</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">{<br></span><span style="color: #0000ff;">private</span><span style="color: #000000;">:<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">enum</span><span style="color: #000000;">{temp&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;IndexOf</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">Tail,&nbsp;T</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">::vale};<br></span><span style="color: #0000ff;">public</span><span style="color: #000000;">:<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">enum</span><span style="color: #000000;">{value&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;temp&nbsp;</span><span style="color: #000000;">==</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">-</span><span style="color: #000000;">1</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">?</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">-</span><span style="color: #000000;">1</span><span style="color: #000000;">&nbsp;:&nbsp;</span><span style="color: #000000;">1</span><span style="color: #000000;">+</span><span style="color: #000000;">temp};<br>};<br></span></div>
</span><br style="font-family: courier new;"><span style="font-family: courier new;">最后一个特化版本用了问号表达式来实现分支判断。</span><span style="font-family: courier new;"></span><br style="font-family: courier new;"><br style="font-family: courier new;"><span style="font-family: courier new;">3.8 追加元素至Typelist</span><br style="font-family: courier new;"><span style="font-family: courier new;"></span><br style="font-family: courier new;"><span style="font-family: courier new;">修改typelist是不可能的，我们以by value方式传回一个新typelist。</span><span style="font-family: courier new;"></span><br style="font-family: courier new;"><br style="font-family: courier new;"><span style="font-family: courier new;">
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #000000;">template&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;TList,&nbsp;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;T</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;Append;<br>template&nbsp;</span><span style="color: #000000;">&lt;&gt;</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;Append</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">NullType,&nbsp;NullType</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">{<br>&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;NullType&nbsp;Result;<br>};<br>template&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;T</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;Append</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">NullType,&nbsp;T</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">{<br>&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;TYPELIST_1(T)&nbsp;Result;<br>};<br>template&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;Head,&nbsp;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;Tail</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br></span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;Append</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">NullType,&nbsp;Typelist</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">Head,&nbsp;Tail</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">{<br>&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;Typelist</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">Head,&nbsp;Tail</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;Result;<br>};<br>template&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;Head,&nbsp;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;Tail,&nbsp;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;T</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br></span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;Append</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">Typelist</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">Head,&nbsp;Tail</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">,&nbsp;T</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">{<br>&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;Typelist</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">Head,&nbsp;typename&nbsp;Append</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">Tail,T</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">::Result</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;Result;<br>};<br></span></div>
</span><br style="font-family: courier new;"><span style="font-family: courier new;">这个实现比较复杂，特别是最后一个偏特化版本，它递归具现Append，每次递归都将tail和待追加型别传递进去。 <br><br><br style="font-family: courier new;"></span><br></span><img src ="http://www.cppblog.com/cuigang/aggbug/40446.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cuigang/" target="_blank">cuigang</a> 2008-01-05 12:19 <a href="http://www.cppblog.com/cuigang/articles/40446.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>《C++设计新思维》读书笔记（18）</title><link>http://www.cppblog.com/cuigang/articles/40443.html</link><dc:creator>cuigang</dc:creator><author>cuigang</author><pubDate>Sat, 05 Jan 2008 04:15:00 GMT</pubDate><guid>http://www.cppblog.com/cuigang/articles/40443.html</guid><wfw:comment>http://www.cppblog.com/cuigang/comments/40443.html</wfw:comment><comments>http://www.cppblog.com/cuigang/articles/40443.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/cuigang/comments/commentRss/40443.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/cuigang/services/trackbacks/40443.html</trackback:ping><description><![CDATA[<span style="font-size: 8pt; font-family: courier new;"><br>3.4 计算长度<br><br>我们用下面代码来计算typelist长度：<br>&nbsp;<br>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #000000;">template&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;TList</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;Length;<br>template&nbsp;</span><span style="color: #000000;">&lt;&gt;</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;Length</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">NullType</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">{<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">enum</span><span style="color: #000000;">&nbsp;{&nbsp;value&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">&nbsp;};<br>};<br>template&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;T,&nbsp;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;U</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br></span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;Length</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">&nbsp;Typelist</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">T,&nbsp;U</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">{<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">enum</span><span style="color: #000000;">&nbsp;{&nbsp;value&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">1</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">+</span><span style="color: #000000;">&nbsp;Length</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">U</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">::value&nbsp;};<br>};</span></div>
<br><br>由Length&lt;T&gt;::value得到的值是一个编译期常数，我们可以用它来定义数组大小，<br><br>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #000000;">std::type_info</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;intsRtti[Length</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">SignedIntegrals</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">::value];</span></div>
<br><br>这个模板代码依靠递归来完成，第一个版本是一个全特化，第二个版本是一个偏特化。<br><br>3.5 间奏曲<br><br>这里有一个问题，在上节的Length实现中，我们能否用迭代来取代递归？答案是否定的。因为我们在编译期编程中，可以使用的仅是：template、编译期整数计算、typedef。<br><br>1、templates：更明确的说是模板特化，提供编译期的if叙述。<br>2、整数计算：提供数值计算能力，用以从型别转为数值。但数值是不可改变的。<br>3、typedef：可视为用来引进&#8220;具名的型别常数&#8221;。它们也是定义之后就冻结，你不能将typedef定义的符号重新定义为另一个型别。<br><br>这些特性决定了我们无法使用迭代。所谓迭代是持有一个迭代器，并改变它，直到某些条件吻合。由于编译期我们没有&#8220;可资变化的任何东西&#8221;，所以无法实现&#8220;迭代&#8221;。所以编译期运算只能象那些纯粹函数型语言，使用大量的递归。<br></span> <img src ="http://www.cppblog.com/cuigang/aggbug/40443.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cuigang/" target="_blank">cuigang</a> 2008-01-05 12:15 <a href="http://www.cppblog.com/cuigang/articles/40443.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>《C++设计新思维》读书笔记（17）</title><link>http://www.cppblog.com/cuigang/articles/39960.html</link><dc:creator>cuigang</dc:creator><author>cuigang</author><pubDate>Sat, 29 Dec 2007 14:08:00 GMT</pubDate><guid>http://www.cppblog.com/cuigang/articles/39960.html</guid><wfw:comment>http://www.cppblog.com/cuigang/comments/39960.html</wfw:comment><comments>http://www.cppblog.com/cuigang/articles/39960.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/cuigang/comments/commentRss/39960.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/cuigang/services/trackbacks/39960.html</trackback:ping><description><![CDATA[<span style="font-size: 8pt; font-family: courier new;"><br>3.2 定义Typelists<br>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #008080;">1</span>&nbsp;<span style="color: #000000;"><br></span><span style="color: #008080;">2</span>&nbsp;<span style="color: #000000;">template&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;T,&nbsp;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;U</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br></span><span style="color: #008080;">3</span>&nbsp;<span style="color: #000000;"></span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;Typelist<br></span><span style="color: #008080;">4</span>&nbsp;<span style="color: #000000;">{<br></span><span style="color: #008080;">5</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;T&nbsp;head;<br></span><span style="color: #008080;">6</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;U&nbsp;Tail;<br></span><span style="color: #008080;">7</span>&nbsp;<span style="color: #000000;">};</span></div>
<br><br>Typelists内部没有任何数值：它的实体是空的。它们存在的理由只是为了携带型别信息。因此，对typelist的任何处理都发生在编译期。此后我们提到一个typelist，指的是一个型别而非一个对象。虽然typlist只有两个参数，但我们可以把任意一个替换为另一个typelist，来达到无限延伸的目的。<br><br>另外我们需要一个零个型别以及一个型别的typelist。对于零个型别，前面提到的NullType就可以，对于一个型别，我们可以这样定义：<br><br>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #008080;">1</span>&nbsp;<span style="color: #000000;">typedef&nbsp;Typelist</span><span style="color: #000000;">&lt;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">,&nbsp;NullType</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;OneTypeOnly;</span></div>
<br><br>3.3 将Typelist生成线性化<br><br>像这样一个typelist<br>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #008080;">1</span><span style="color: #000000;"><br></span><span style="color: #008080;">2</span>&nbsp;<span style="color: #000000;">typedef&nbsp;Typlist</span><span style="color: #000000;">&lt;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">,&nbsp;Typelist</span><span style="color: #000000;">&lt;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">,&nbsp;Typelist</span><span style="color: #000000;">&lt;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">,&nbsp;Typelist</span><span style="color: #000000;">&lt;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">,&nbsp;</span><span style="color: #0000ff;">int</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;Int4Type;</span></div>
<br><br>它太Lisp了，我们定义一系列的宏来完成它，这样我们可以忘记尖括号间的空格。<br><br>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #008080;">1</span>&nbsp;<span style="color: #0000ff;">#define</span><span style="color: #000000;">&nbsp;TYPELIST_1(T1)&nbsp;Typelist&lt;T1,&nbsp;NullType&gt;</span><span style="color: #000000;"><br></span><span style="color: #008080;">2</span>&nbsp;<span style="color: #000000;"></span><span style="color: #0000ff;">#define</span><span style="color: #000000;">&nbsp;TYPELIST_2(T1,&nbsp;T2)&nbsp;Typelist&lt;T1,&nbsp;TYPELIST_1(T2)&nbsp;&gt;</span><span style="color: #000000;"><br></span><span style="color: #008080;">3</span>&nbsp;<span style="color: #000000;"></span><span style="color: #0000ff;">#define</span><span style="color: #000000;">&nbsp;TYPELIST_3(T1,&nbsp;T2,&nbsp;T3)&nbsp;Typelist&lt;T1,&nbsp;TYPELIST_2(T2,&nbsp;T3)&nbsp;&gt;</span><span style="color: #000000;"><br></span><span style="color: #008080;">4</span>&nbsp;<span style="color: #000000;"></span><span style="color: #0000ff;">#define</span><span style="color: #000000;">&nbsp;TYPELIST_4(T1,&nbsp;T2,&nbsp;T3,&nbsp;T4)&nbsp;Typelist&lt;T1,&nbsp;TYPELIST_3(T2,&nbsp;T3,&nbsp;T4)&nbsp;&gt;</span><span style="color: #000000;"><br></span><span style="color: #008080;">5</span>&nbsp;<span style="color: #000000;"></span><span style="color: #008000;">//</span><span style="color: #008000;">etc</span><span style="color: #008000;"><br></span><span style="color: #008080;">6</span>&nbsp;<span style="color: #008000;"></span><span style="color: #0000ff;">#define</span><span style="color: #000000;">&nbsp;TYPELIST_50(/*&nbsp;*/)&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;"><img src="http://www.cppblog.com/Images/dot.gif"></span></div>
<br><br>这样前面的 Int4Type 就可以这样定义<br><br>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #008080;">1</span>&nbsp;<span style="color: #000000;">typedef&nbsp;Int4Type&nbsp;TYPELIST_4(</span><span style="color: #0000ff;">int</span><span style="color: #000000;">,&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">,&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">,&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">)&nbsp;Int4Type;</span></div>
<br><br>这只是包装手法的一个开端。我们访问Int4Type的最后一个元素还比较麻烦，需要<br><br>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #008080;">1</span>&nbsp;<span style="color: #000000;">Int4Type::Tail::Tail::Tail;</span></div>
<br><br>我们还要进一步来考虑它操作的问题。<br><br><br>&nbsp;<br></span><img src ="http://www.cppblog.com/cuigang/aggbug/39960.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cuigang/" target="_blank">cuigang</a> 2007-12-29 22:08 <a href="http://www.cppblog.com/cuigang/articles/39960.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>《C++设计新思维》读书笔记（16）</title><link>http://www.cppblog.com/cuigang/articles/39959.html</link><dc:creator>cuigang</dc:creator><author>cuigang</author><pubDate>Sat, 29 Dec 2007 14:05:00 GMT</pubDate><guid>http://www.cppblog.com/cuigang/articles/39959.html</guid><wfw:comment>http://www.cppblog.com/cuigang/comments/39959.html</wfw:comment><comments>http://www.cppblog.com/cuigang/articles/39959.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/cuigang/comments/commentRss/39959.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/cuigang/services/trackbacks/39959.html</trackback:ping><description><![CDATA[<span style="font-size: 8pt;"><span style="font-family: courier new;"></span><br style="font-family: courier new;"><span style="font-family: courier new;">3. Typelists</span><br><br style="font-family: courier new;"><span style="font-family: courier new;">Typelists是一个用来操作一大群型别的C++工具。就像lists对数值提供各种基本操作一样，typelists对型别也提供相同操作。</span><br style="font-family: courier new;"><br style="font-family: courier new;"><span style="font-family: courier new;">有些设计模式具体指定并操作一群型别，其中也许有继承关系（但也许没有）。显著的例子是abstract factory和visitor。如果以传统编程技术来操作一大群型别，将是全然的重复工作。如此重复会导致隐微的代码膨胀。多数人不会想到其实它可以比现在更好。Typelists带给你一种能力，可以将经常性的宏工作自动化。Typelists将来自外星球的强大威力带到C++中，让它得以支持新而有趣的一些手法。</span><br style="font-family: courier new;"><br style="font-family: courier new;"><span style="font-family: courier new;">3.1 Typelists的必要性</span><br style="font-family: courier new;"><br style="font-family: courier new;"><span style="font-family: courier new;">有时候你必须针对某些型别重复撰写相同代码，而templates无法帮上忙。假如有一个abstract factory，像这样：</span><br style="font-family: courier new;"><br style="font-family: courier new;"><span style="font-family: courier new;"></span><span style="font-family: courier new;"></span>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #008080;">1</span>&nbsp;<span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;WidgetFactory<br></span><span style="color: #008080;">2</span>&nbsp;<span style="color: #000000;">{<br></span><span style="color: #008080;">3</span>&nbsp;<span style="color: #000000;"></span><span style="color: #0000ff;">public</span><span style="color: #000000;">:<br></span><span style="color: #008080;">4</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">virtual</span><span style="color: #000000;">&nbsp;Window</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;CreateWindow()&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">;<br></span><span style="color: #008080;">5</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">virtual</span><span style="color: #000000;">&nbsp;Button</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;CreateButton()&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">;<br></span><span style="color: #008080;">6</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">virtual</span><span style="color: #000000;">&nbsp;ScrollBar</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;CreateScrollBar()&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">;<br></span><span style="color: #008080;">7</span>&nbsp;<span style="color: #000000;">};</span></div>
<br style="font-family: courier new;"><br style="font-family: courier new;"><span style="font-family: courier new;">如果你想将Abstract Factory概念泛化，不只生成Window、Button、ScrollBar，而是任意型别。怎么办？</span><br style="font-family: courier new;"><br style="font-family: courier new;"><span style="font-family: courier new;">如果你不试图泛化基本概念，就不太有机会泛化这些概念的具象实体。虽然抽象基类很简单，但是你会陷入无穷无尽的派生类生成器中。</span><br style="font-family: courier new;"><br style="font-family: courier new;"><span style="font-family: courier new;">我们希望能够这样去使用一个abstract factory：</span><br style="font-family: courier new;">
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #008080;">1</span>&nbsp;<span style="color: #000000;"><br></span><span style="color: #008080;">2</span>&nbsp;<span style="color: #000000;">template&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;T</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br></span><span style="color: #008080;">3</span>&nbsp;<span style="color: #000000;">T</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;MakeRedWidget(WidgetFactory</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">&nbsp;factory)<br></span><span style="color: #008080;">4</span>&nbsp;<span style="color: #000000;">{<br></span><span style="color: #008080;">5</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;T</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;pW&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;factory.Create</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">T</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">();<br></span><span style="color: #008080;">6</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;pW&nbsp;</span><span style="color: #000000;">-&gt;</span><span style="color: #000000;">&nbsp;SetColor(RED);<br></span><span style="color: #008080;">7</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;pW;<br></span><span style="color: #008080;">8</span>&nbsp;<span style="color: #000000;">}</span></div>
<span style="font-family: courier new;"></span><br style="font-family: courier new;"><br style="font-family: courier new;"><span style="font-family: courier new;">实际这是不可能的，如果Create不是虚函数，那么你就陷入了长长的Switch...case...之中，如果它是虚函数，那么虚函数不能是模板。</span><br style="font-family: courier new;"><span style="font-family: courier new;">Typelists将使Abstract Factories泛化成真，并带来更多其它利益。</span><br style="font-family: courier new;"><br style="font-family: courier new;"></span><img src ="http://www.cppblog.com/cuigang/aggbug/39959.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cuigang/" target="_blank">cuigang</a> 2007-12-29 22:05 <a href="http://www.cppblog.com/cuigang/articles/39959.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>《C++设计新思维》读书笔记（15）</title><link>http://www.cppblog.com/cuigang/articles/39621.html</link><dc:creator>cuigang</dc:creator><author>cuigang</author><pubDate>Tue, 25 Dec 2007 13:43:00 GMT</pubDate><guid>http://www.cppblog.com/cuigang/articles/39621.html</guid><wfw:comment>http://www.cppblog.com/cuigang/comments/39621.html</wfw:comment><comments>http://www.cppblog.com/cuigang/articles/39621.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/cuigang/comments/commentRss/39621.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/cuigang/services/trackbacks/39621.html</trackback:ping><description><![CDATA[<div class="Section1"><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;" lang="EN-US"> </span></font><st1:chsdate isrocdate="False" islunardate="False" day="30" month="12" year="1899" w:st="on"><font face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;;" lang="EN-US">2.10.2</span></font></st1:chsdate><font face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;;" lang="EN-US">
</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">侦测基本型别（略）</span></font><font face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;;" lang="EN-US">'<br>2.10.3 </span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">优化的参数型别（略）<br></span></font><font face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;;" lang="EN-US">2.10.4 </span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">卸除饰词</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;" lang="EN-US"><o:p></o:p></span></font>
<p class="MsoNormal" style="text-align: left;" align="left"><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">下面是一个</span></font><font face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;;" lang="EN-US">&#8220;const
</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">卸除器</span></font><font face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;;" lang="EN-US">&#8221;</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">：</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;" lang="EN-US"><o:p></o:p></span></font></p>
<p class="MsoNormal" style="text-align: left;" align="left"><font color="green" face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;; color: green;" lang="EN-US">
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #008080;">&nbsp;1</span>&nbsp;<span style="color: #000000;">template</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;">&nbsp;2</span>&nbsp;<span style="color: #000000;"></span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;TypeTraits<br></span><span style="color: #008080;">&nbsp;3</span>&nbsp;<span style="color: #000000;">{<br></span><span style="color: #008080;">&nbsp;4</span>&nbsp;<span style="color: #000000;"></span><span style="color: #0000ff;">private</span><span style="color: #000000;">:<br></span><span style="color: #008080;">&nbsp;5</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;template</span><span style="color: #000000;">&lt;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;U</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;UnConst<br></span><span style="color: #008080;">&nbsp;6</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;{<br></span><span style="color: #008080;">&nbsp;7</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;U&nbsp;Result;<br></span><span style="color: #008080;">&nbsp;8</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;};<br></span><span style="color: #008080;">&nbsp;9</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;template</span><span style="color: #000000;">&lt;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;U</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;UnConst</span><span style="color: #000000;">&lt;</span><span style="color: #0000ff;">const</span><span style="color: #000000;">&nbsp;U</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br></span><span style="color: #008080;">10</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;{<br></span><span style="color: #008080;">11</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;U&nbsp;Result;<br></span><span style="color: #008080;">12</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;};<br></span><span style="color: #008080;">13</span>&nbsp;<span style="color: #000000;"></span><span style="color: #0000ff;">public</span><span style="color: #000000;">:<br></span><span style="color: #008080;">14</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;UnConst</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">T</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">::Result&nbsp;NonConstType;<br></span><span style="color: #008080;">15</span>&nbsp;<span style="color: #000000;">};</span></div>
<br></span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;" lang="EN-US"><o:p></o:p></span></font></p>
<p class="MsoNormal" style="text-align: left;" align="left"><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;" lang="EN-US"></span></font><st1:chsdate isrocdate="False" islunardate="False" day="30" month="12" year="1899" w:st="on"><font face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;;" lang="EN-US">2.10.5</span></font></st1:chsdate><font face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;;" lang="EN-US">
</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">运用</span></font><font face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;;" lang="EN-US">TypeTraits</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;" lang="EN-US"><o:p></o:p></span></font></p>
<p class="MsoNormal" style="text-align: left;" align="left"><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">这里实作一个调用</span></font><font face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;;" lang="EN-US">BitBlast</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">的例子：</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;" lang="EN-US">&nbsp;<o:p></o:p></span></font></p>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #008080;">&nbsp;<span style="font-family: courier new;">1</span></span><span style="font-family: courier new;">&nbsp;</span><span style="color: #0000ff; font-family: courier new;">enum</span><span style="color: #000000; font-family: courier new;">&nbsp;CopyAlgoSelector{Conservative,&nbsp;Fast};<br></span><span style="color: #008080; font-family: courier new;">&nbsp;2</span><span style="font-family: courier new;">&nbsp;</span><span style="color: #000000; font-family: courier new;"><br></span><span style="color: #008080; font-family: courier new;">&nbsp;3</span><span style="font-family: courier new;">&nbsp;</span><span style="color: #000000; font-family: courier new;"></span><span style="color: #008000; font-family: courier new;">//&nbsp;Conservative&nbsp;routine-works&nbsp;for&nbsp;any&nbsp;type<br></span><span style="color: #008080; font-family: courier new;">&nbsp;4</span><span style="font-family: courier new;">&nbsp;</span><span style="color: #008000; font-family: courier new;"></span><span style="color: #000000; font-family: courier new;">template&nbsp;&lt;typename&nbsp;InIt,&nbsp;typename&nbsp;OutIt&gt;<br></span><span style="color: #008080; font-family: courier new;">&nbsp;5</span><span style="font-family: courier new;">&nbsp;</span><span style="color: #000000; font-family: courier new;">OutIt&nbsp;CopyImpl(InIt&nbsp;first,&nbsp;InIt&nbsp;last,&nbsp;OutIt&nbsp;result,&nbsp;Int2Type&lt;Conservative&gt;)<br></span><span style="color: #008080; font-family: courier new;">&nbsp;6</span><span style="font-family: courier new;">&nbsp;</span><span style="color: #000000; font-family: courier new;">{<br></span><span style="color: #008080; font-family: courier new;">&nbsp;7</span><span style="font-family: courier new;">&nbsp;</span><span style="color: #000000; font-family: courier new;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff; font-family: courier new;">for</span><span style="color: #000000; font-family: courier new;">(;&nbsp;first&nbsp;!=&nbsp;last;&nbsp;++first,&nbsp;++result)<br></span><span style="color: #008080; font-family: courier new;">&nbsp;8</span><span style="font-family: courier new;">&nbsp;</span><span style="color: #000000; font-family: courier new;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*result&nbsp;=&nbsp;*first;<br></span><span style="color: #008080; font-family: courier new;">&nbsp;9</span><span style="font-family: courier new;">&nbsp;</span><span style="color: #000000; font-family: courier new;">}<br></span><span style="color: #008080; font-family: courier new;">10</span><span style="font-family: courier new;">&nbsp;</span><span style="color: #000000; font-family: courier new;"><br></span><span style="color: #008080; font-family: courier new;">11</span><span style="font-family: courier new;">&nbsp;</span><span style="color: #000000; font-family: courier new;"></span><span style="color: #008000; font-family: courier new;">//&nbsp;Fast&nbsp;routine-works&nbsp;only&nbsp;for&nbsp;pointers&nbsp;to&nbsp;raw&nbsp;data<br></span><span style="color: #008080; font-family: courier new;">12</span><span style="font-family: courier new;">&nbsp;</span><span style="color: #008000; font-family: courier new;"></span><span style="color: #000000; font-family: courier new;">template&nbsp;&lt;typename&nbsp;InIt,&nbsp;typename&nbsp;OutIt&gt;<br></span><span style="color: #008080; font-family: courier new;">13</span><span style="font-family: courier new;">&nbsp;</span><span style="color: #000000; font-family: courier new;">OutIt&nbsp;CopyImpl(InIt&nbsp;first,&nbsp;InIt&nbsp;last,&nbsp;OutIt&nbsp;result,&nbsp;Int2Type&lt;Fast&gt;)<br></span><span style="color: #008080; font-family: courier new;">14</span><span style="font-family: courier new;">&nbsp;</span><span style="color: #000000; font-family: courier new;">{<br></span><span style="color: #008080; font-family: courier new;">15</span><span style="font-family: courier new;">&nbsp;</span><span style="color: #000000; font-family: courier new;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff; font-family: courier new;">const</span><span style="color: #000000; font-family: courier new;">&nbsp;size_t&nbsp;n&nbsp;=&nbsp;last&nbsp;-&nbsp;first;<br></span><span style="color: #008080; font-family: courier new;">16</span><span style="font-family: courier new;">&nbsp;</span><span style="color: #000000; font-family: courier new;">&nbsp;&nbsp;&nbsp;&nbsp;BitBlast(first,&nbsp;result,&nbsp;n&nbsp;*&nbsp;</span><span style="color: #0000ff; font-family: courier new;">sizeof</span><span style="color: #000000; font-family: courier new;">(*first));<br></span><span style="color: #008080; font-family: courier new;">17</span><span style="font-family: courier new;">&nbsp;</span><span style="color: #000000; font-family: courier new;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff; font-family: courier new;">return</span><span style="color: #000000; font-family: courier new;">&nbsp;result&nbsp;+&nbsp;n;<br></span><span style="color: #008080; font-family: courier new;">18</span><span style="font-family: courier new;">&nbsp;</span><span style="color: #000000; font-family: courier new;">}<br></span><span style="color: #008080; font-family: courier new;">19</span><span style="font-family: courier new;">&nbsp;</span><span style="color: #000000; font-family: courier new;"><br></span><span style="color: #008080; font-family: courier new;">20</span><span style="font-family: courier new;">&nbsp;</span><span style="color: #000000; font-family: courier new;">template&lt;typename&nbsp;T&gt;&nbsp;</span><span style="color: #0000ff; font-family: courier new;">struct</span><span style="color: #000000; font-family: courier new;">&nbsp;SupportsBitwiseCopy<br></span><span style="color: #008080; font-family: courier new;">21</span><span style="font-family: courier new;">&nbsp;</span><span style="color: #000000; font-family: courier new;">{<br></span><span style="color: #008080; font-family: courier new;">22</span><span style="font-family: courier new;">&nbsp;</span><span style="color: #000000; font-family: courier new;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff; font-family: courier new;">enum</span><span style="color: #000000; font-family: courier new;">{result&nbsp;=&nbsp;TypeTraits&lt;T&gt;::isStdFundamental};<br></span><span style="color: #008080; font-family: courier new;">23</span><span style="font-family: courier new;">&nbsp;</span><span style="color: #000000; font-family: courier new;">}<br></span><span style="color: #008080; font-family: courier new;">24</span><span style="font-family: courier new;">&nbsp;</span><span style="color: #000000; font-family: courier new;"><br></span><span style="color: #008080; font-family: courier new;">25</span><span style="font-family: courier new;">&nbsp;</span><span style="color: #000000; font-family: courier new;">template&nbsp;&lt;typename&nbsp;InIt,&nbsp;typename&nbsp;OutIt&gt;<br></span><span style="color: #008080; font-family: courier new;">26</span><span style="font-family: courier new;">&nbsp;</span><span style="color: #000000; font-family: courier new;">OutIt&nbsp;Copy(InIt&nbsp;first,&nbsp;InIt&nbsp;last,&nbsp;OutIt&nbsp;result)<br></span><span style="color: #008080; font-family: courier new;">27</span><span style="font-family: courier new;">&nbsp;</span><span style="color: #000000; font-family: courier new;">{<br></span><span style="color: #008080; font-family: courier new;">28</span><span style="font-family: courier new;">&nbsp;</span><span style="color: #000000; font-family: courier new;">&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;TypeTraits&lt;InIt&gt;::PointeeType&nbsp;SrcPointee;<br></span><span style="color: #008080; font-family: courier new;">29</span><span style="font-family: courier new;">&nbsp;</span><span style="color: #000000; font-family: courier new;">&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;TypeTraits&lt;OutIt&gt;::PointeeType&nbsp;DestPointee;<br></span><span style="color: #008080; font-family: courier new;">30</span><span style="font-family: courier new;">&nbsp;</span><span style="color: #000000; font-family: courier new;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff; font-family: courier new;">enum</span><span style="color: #000000; font-family: courier new;">&nbsp;{&nbsp;copyAlgo&nbsp;=<br></span><span style="color: #008080; font-family: courier new;">31</span><span style="font-family: courier new;">&nbsp;</span><span style="color: #000000; font-family: courier new;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TypeTraits&lt;InIt&gt;::IsPointer&nbsp;&amp;&amp;<br></span><span style="color: #008080; font-family: courier new;">32</span><span style="font-family: courier new;">&nbsp;</span><span style="color: #000000; font-family: courier new;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TypeTraits&lt;OutIt&gt;::IsPointer&nbsp;&amp;&amp;<br></span><span style="color: #008080; font-family: courier new;">33</span><span style="font-family: courier new;">&nbsp;</span><span style="color: #000000; font-family: courier new;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SupportsBitwiseCopy&lt;SrcPointee&gt;::result&nbsp;&amp;&amp;<br></span><span style="color: #008080; font-family: courier new;">34</span><span style="font-family: courier new;">&nbsp;</span><span style="color: #000000; font-family: courier new;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SupportsBitwiseCopy&lt;DestPointee&gt;::result&nbsp;&amp;&amp;<br></span><span style="color: #008080; font-family: courier new;">35</span><span style="font-family: courier new;">&nbsp;</span><span style="color: #000000; font-family: courier new;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff; font-family: courier new;">sizeof</span><span style="color: #000000; font-family: courier new;">(SrcPointee)&nbsp;==&nbsp;</span><span style="color: #0000ff; font-family: courier new;">sizeof</span><span style="color: #000000; font-family: courier new;">(DestPointee)&nbsp;};<br></span><span style="color: #008080; font-family: courier new;">36</span><span style="font-family: courier new;">&nbsp;</span><span style="color: #000000; font-family: courier new;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff; font-family: courier new;">return</span><span style="color: #000000; font-family: courier new;">&nbsp;CopyImpl(first,&nbsp;last,&nbsp;Int2Type&lt;useBitBlast&gt;);<br></span><span style="color: #008080; font-family: courier new;">37</span><span style="font-family: courier new;">&nbsp;</span><span style="color: #000000; font-family: courier new;">}</span></div>
<br>
<p class="MsoNormal" style="text-align: left;" align="left"><font color="green" face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;; color: green;" lang="EN-US"></span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;" lang="EN-US"><o:p></o:p></span></font></p>
<p class="MsoNormal" style="text-align: left;" align="left"><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">对于一个</span></font><font face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;;" lang="EN-US">POD</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">结构（</span></font><font face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;;" lang="EN-US">plain old data</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">），即</span></font><font face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;;" lang="EN-US">C
struct</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">，只有数据没有其它任何东西。因为无法甄别其类型，会调用慢速版本。我们可以这样做，让它调用快速版本，假如</span></font><font face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;;" lang="EN-US">POD</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">结构为</span></font><font face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;;" lang="EN-US">Mytype</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">。</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;" lang="EN-US"><o:p></o:p></span></font></p>
<p class="MsoNormal" style="text-align: left;" align="left"><font color="green" face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;; color: green;" lang="EN-US">
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #008080;">1</span>&nbsp;<span style="color: #000000;">template</span><span style="color: #000000;">&lt;&gt;</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;SupportsBitwiseCopy</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">MyTyee</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br></span><span style="color: #008080;">2</span>&nbsp;<span style="color: #000000;">{<br></span><span style="color: #008080;">3</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">enum</span><span style="color: #000000;">&nbsp;{result&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">true</span><span style="color: #000000;">};<br></span><span style="color: #008080;">4</span>&nbsp;<span style="color: #000000;">};</span></div>
<br></span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;" lang="EN-US"><o:p></o:p></span></font></p>
</div><img src ="http://www.cppblog.com/cuigang/aggbug/39621.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cuigang/" target="_blank">cuigang</a> 2007-12-25 21:43 <a href="http://www.cppblog.com/cuigang/articles/39621.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>《C++设计新思维》读书笔记（14）</title><link>http://www.cppblog.com/cuigang/articles/39533.html</link><dc:creator>cuigang</dc:creator><author>cuigang</author><pubDate>Mon, 24 Dec 2007 13:55:00 GMT</pubDate><guid>http://www.cppblog.com/cuigang/articles/39533.html</guid><wfw:comment>http://www.cppblog.com/cuigang/comments/39533.html</wfw:comment><comments>http://www.cppblog.com/cuigang/articles/39533.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/cuigang/comments/commentRss/39533.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/cuigang/services/trackbacks/39533.html</trackback:ping><description><![CDATA[<st1:chsdate isrocdate="False" islunardate="False" day="30" month="12" year="1899" w:st="on"><font face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;;" lang="EN-US">2.10.1</span></font></st1:chsdate><font face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;;" lang="EN-US">
</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">实作出</span></font><font face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;;" lang="EN-US">Pointer Traits</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;" lang="EN-US"><o:p></o:p></span></font>
<p class="MsoNormal" style="text-align: left;" align="left"><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">大部分</span></font><font face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;;" lang="EN-US">type
traits</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">的实作都依赖全特化或偏特化。下面代码用来判断型别</span></font><font face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;;" lang="EN-US">T</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">是否为指针：</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;" lang="EN-US"><o:p></o:p></span></font></p>
<p class="MsoNormal" style="text-align: left;" align="left"><font face="宋体" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;; color: green;" lang="EN-US">
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #008080;">&nbsp;1</span>&nbsp;<span style="color: #000000;">template</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;">&nbsp;2</span>&nbsp;<span style="color: #000000;"></span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;TypeTraits<br></span><span style="color: #008080;">&nbsp;3</span>&nbsp;<span style="color: #000000;">{<br></span><span style="color: #008080;">&nbsp;4</span>&nbsp;<span style="color: #000000;"></span><span style="color: #0000ff;">private</span><span style="color: #000000;">:<br></span><span style="color: #008080;">&nbsp;5</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;template</span><span style="color: #000000;">&lt;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;U</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;PointerTraits<br></span><span style="color: #008080;">&nbsp;6</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;{<br></span><span style="color: #008080;">&nbsp;7</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">enum</span><span style="color: #000000;">&nbsp;{&nbsp;result&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">false</span><span style="color: #000000;">&nbsp;};<br></span><span style="color: #008080;">&nbsp;8</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;NullType&nbsp;PointeeType;<br></span><span style="color: #008080;">&nbsp;9</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;};<br></span><span style="color: #008080;">10</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;template</span><span style="color: #000000;">&lt;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;U</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;PointerTraits</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">U</span><span style="color: #000000;">*&gt;</span><span style="color: #000000;"><br></span><span style="color: #008080;">11</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;{<br></span><span style="color: #008080;">12</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">enum</span><span style="color: #000000;">&nbsp;{&nbsp;result&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">true</span><span style="color: #000000;">&nbsp;};<br></span><span style="color: #008080;">13</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;U&nbsp;PointeeType;<br></span><span style="color: #008080;">14</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;};<br></span><span style="color: #008080;">15</span>&nbsp;<span style="color: #000000;"></span><span style="color: #0000ff;">public</span><span style="color: #000000;">:<br></span><span style="color: #008080;">16</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">enum</span><span style="color: #000000;">&nbsp;{&nbsp;isPointer&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;PointerTraits</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">T</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">::result&nbsp;};<br></span><span style="color: #008080;">17</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;PointerTraits</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">T</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">::Pointeetype&nbsp;PointeeType;<br></span><span style="color: #008080;">18</span>&nbsp;<span style="color: #000000;">};</span></div>
<br></span><br><span style="font-size: 9pt; font-family: 宋体;">对于一个指针型别，</span></font><font face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;;" lang="EN-US">PointerTraits</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">的偏特化版本更适合。所以对于一个非指针型别，</span></font><font face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;;" lang="EN-US">result</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">为</span></font><font face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;;" lang="EN-US">false</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">，所谓被指型别</span></font><font face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;;" lang="EN-US">PointeeType</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">不能拿来使用，只是一个不能被使用的占位型别（</span></font><font face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;;" lang="EN-US">placeholder type</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">）。</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;" lang="EN-US"><o:p></o:p></span></font></p>
<p class="MsoNormal" style="text-align: left;" align="left"><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">对于指向成员函数的指针，我们需要这样做：</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;" lang="EN-US"><o:p></o:p></span></font></p>
<font color="green" face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;; color: green;" lang="EN-US">
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #008080;">&nbsp;1</span>&nbsp;<span style="color: #000000;">template</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;">&nbsp;2</span>&nbsp;<span style="color: #000000;"></span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;TypeTraits<br></span><span style="color: #008080;">&nbsp;3</span>&nbsp;<span style="color: #000000;">{<br></span><span style="color: #008080;">&nbsp;4</span>&nbsp;<span style="color: #000000;"></span><span style="color: #0000ff;">private</span><span style="color: #000000;">:<br></span><span style="color: #008080;">&nbsp;5</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;template&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;U</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;PToMTraits<br></span><span style="color: #008080;">&nbsp;6</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;{<br></span><span style="color: #008080;">&nbsp;7</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">enum</span><span style="color: #000000;">{result&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">false</span><span style="color: #000000;">};<br></span><span style="color: #008080;">&nbsp;8</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;};<br></span><span style="color: #008080;">&nbsp;9</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;template&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;U,&nbsp;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;V</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br></span><span style="color: #008080;">10</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;PToMTraits</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">U,&nbsp;V::</span><span style="color: #000000;">*&gt;</span><span style="color: #000000;"><br></span><span style="color: #008080;">11</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;{<br></span><span style="color: #008080;">12</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">enum</span><span style="color: #000000;">&nbsp;{reulst&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">true</span><span style="color: #000000;">&nbsp;};<br></span><span style="color: #008080;">13</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;}<br></span><span style="color: #008080;">14</span>&nbsp;<span style="color: #000000;"></span><span style="color: #0000ff;">public</span><span style="color: #000000;">:<br></span><span style="color: #008080;">15</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">enum</span><span style="color: #000000;">&nbsp;{&nbsp;isMemberPointer&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;PToMTraits</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">T</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">::result};<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;"></span></div>
<br></span></font><img src ="http://www.cppblog.com/cuigang/aggbug/39533.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cuigang/" target="_blank">cuigang</a> 2007-12-24 21:55 <a href="http://www.cppblog.com/cuigang/articles/39533.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>《C++设计新思维》读书笔记（13）</title><link>http://www.cppblog.com/cuigang/articles/39344.html</link><dc:creator>cuigang</dc:creator><author>cuigang</author><pubDate>Sun, 23 Dec 2007 04:14:00 GMT</pubDate><guid>http://www.cppblog.com/cuigang/articles/39344.html</guid><wfw:comment>http://www.cppblog.com/cuigang/comments/39344.html</wfw:comment><comments>http://www.cppblog.com/cuigang/articles/39344.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/cuigang/comments/commentRss/39344.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/cuigang/services/trackbacks/39344.html</trackback:ping><description><![CDATA[<div class="Section1"><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;" lang="EN-US"></span></font><font face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;;" lang="EN-US">2.8
type_info</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">的一个外覆类（</span></font><font face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;;" lang="EN-US">Wrapper</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">）</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;" lang="EN-US"><o:p></o:p></span></font>
<p class="MsoNormal" style="text-align: left;" align="left"><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">因为</span></font><font face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;;" lang="EN-US">std::type_info</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">类不太好用，作者提供的</span></font><font face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;;" lang="EN-US">Loki</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">库对其包装了一下，这节对其进行介绍，省去。</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;" lang="EN-US"><o:p></o:p></span></font></p>
<p class="MsoNormal" style="text-align: left;" align="left"><font face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;;" lang="EN-US">2.9
NullType </span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">和</span></font><font face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;;" lang="EN-US"> EmptyType</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;" lang="EN-US"><o:p></o:p></span></font></p>
<p class="MsoNormal" style="text-align: left;" align="left"><font face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;;" lang="EN-US">Loki</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">定义了两个非常简单的型别：</span></font><font face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;;" lang="EN-US">NullType </span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">和</span></font><font face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;;" lang="EN-US">
EmptyType</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">。可以作为型别计算的边界。</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;" lang="EN-US"><o:p></o:p></span></font></p>
<p class="MsoNormal" style="text-align: left;" align="left"><font color="green" face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;; color: green;" lang="EN-US">
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #008080;">1</span>&nbsp;<span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;NullType;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">没有定义</span><span style="color: #008000;"><br></span><span style="color: #008080;">2</span>&nbsp;<span style="color: #008000;"></span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;EmptyType{};</span></div>
<br></span></font><font color="green" face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;; color: green;" lang="EN-US"></span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;" lang="EN-US"><o:p></o:p></span></font></p>
<p class="MsoNormal" style="text-align: left;" align="left"><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">第</span></font><font face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;;" lang="EN-US">3</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">章会展示其用途。</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;" lang="EN-US"><o:p></o:p></span></font></p>
<p class="MsoNormal" style="text-align: left;" align="left"><font face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;;" lang="EN-US">2.10
Type Traits</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;" lang="EN-US"><o:p></o:p></span></font></p>
<p class="MsoNormal" style="text-align: left;" align="left"><font face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;;" lang="EN-US">Traits
</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">是一种</span></font><font face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;;" lang="EN-US">&#8220;</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">可于编译期根据型别作判断</span></font><font face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;;" lang="EN-US">&#8221;</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">的泛型技术，很想你在执行期根据数值进行判断一样。假设你想实作</span></font><font face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;;" lang="EN-US">
Copying</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">算法：</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;" lang="EN-US"><o:p></o:p></span></font></p>
<p class="MsoNormal" style="text-align: left;" align="left"><font color="green" face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;; color: green;" lang="EN-US">
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #008080;">1</span>&nbsp;<span style="color: #000000;">template&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">typename&nbsp;InIt,&nbsp;typename&nbsp;OutIt</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br></span><span style="color: #008080;">2</span>&nbsp;<span style="color: #000000;">OutIt&nbsp;Copy(InIt&nbsp;first,&nbsp;InIt&nbsp;last,&nbsp;OutIt&nbsp;result)<br></span><span style="color: #008080;">3</span>&nbsp;<span style="color: #000000;">{<br></span><span style="color: #008080;">4</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">for</span><span style="color: #000000;">(;&nbsp;fist</span><span style="color: #000000;">!=</span><span style="color: #000000;">last;&nbsp;</span><span style="color: #000000;">++</span><span style="color: #000000;">first,&nbsp;</span><span style="color: #000000;">++</span><span style="color: #000000;">result)<br></span><span style="color: #008080;">5</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">result&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">first;<br></span><span style="color: #008080;">6</span>&nbsp;<span style="color: #000000;">}</span></div>
<br></span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;" lang="EN-US"><o:p></o:p></span></font></p>
<p class="MsoNormal" style="text-align: left;" align="left"><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">另外假设你有一个针对硬件优化的非常快的内建函数，你希望尽可能发挥改函数的好处。</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;" lang="EN-US">&nbsp;<o:p></o:p></span></font></p>
<p class="MsoNormal" style="text-align: left;" align="left"><font color="green" face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;; color: green;" lang="EN-US">
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #008080;">1</span>&nbsp;<span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;BitBlast(</span><span style="color: #0000ff;">const</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;src,&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;dest,&nbsp;size_t&nbsp;bytes);</span></div>
<br></span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;" lang="EN-US"><o:p></o:p></span></font></p>
<p class="MsoNormal" style="text-align: left;" align="left"><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">这是一个只针对基本型别并有着简朴旧式结构的实作，你不能将它用于拥有</span></font><font face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;;" lang="EN-US">&#8220;nontrivial copy</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">构造函数</span></font><font face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;;" lang="EN-US">&#8221;</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">的型别上。你可能需要对型别判断，以判断是否可以利用</span></font><font face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;;" lang="EN-US">BitBlast</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">，以便对基本型别快速执行。</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;" lang="EN-US"><o:p></o:p></span></font></p>
<p class="MsoNormal" style="text-align: left;" align="left"><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">你需要判断：</span></font><font face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;;" lang="EN-US"><br>
1</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">、</span></font><font face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;;" lang="EN-US">InIt </span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">和</span></font><font face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;;" lang="EN-US"> OutIt</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">是一般指针吗？（针对</span></font><font face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;;" lang="EN-US">iterator</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">迭代器而言）</span></font><font face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;;" lang="EN-US"><br>
2</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">、</span></font><font face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;;" lang="EN-US">InIt </span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">和</span></font><font face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;;" lang="EN-US"> OutIt</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">所指的型别可以</span></font><font face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;;" lang="EN-US">bitwise copy</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">（位逐一拷贝）吗？</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;" lang="EN-US"><o:p></o:p></span></font></p>
<p class="MsoNormal" style="text-align: left;" align="left"><font face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;;" lang="EN-US">Type
traits </span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">有助于解决这样的问题。</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;" lang="EN-US"><o:p></o:p></span></font></p>
</div><img src ="http://www.cppblog.com/cuigang/aggbug/39344.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cuigang/" target="_blank">cuigang</a> 2007-12-23 12:14 <a href="http://www.cppblog.com/cuigang/articles/39344.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>《C++设计新思维》读书笔记（12）</title><link>http://www.cppblog.com/cuigang/articles/39343.html</link><dc:creator>cuigang</dc:creator><author>cuigang</author><pubDate>Sun, 23 Dec 2007 04:12:00 GMT</pubDate><guid>http://www.cppblog.com/cuigang/articles/39343.html</guid><wfw:comment>http://www.cppblog.com/cuigang/comments/39343.html</wfw:comment><comments>http://www.cppblog.com/cuigang/articles/39343.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/cuigang/comments/commentRss/39343.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/cuigang/services/trackbacks/39343.html</trackback:ping><description><![CDATA[<div class="Section1"><font face="Courier new" size="1"><span style="font-size: 9pt; font-family: &quot;courier new&quot;;" lang="EN-US">2.7
</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">编译期间侦测可转换性和继承性</span></font><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;" lang="EN-US"><o:p></o:p></span></font>
<p class="MsoNormal" style="text-align: left;" align="left"><font face="宋体" size="1"><span style="font-size: 9pt; font-family: 宋体;">在泛型编程中，经常