﻿<?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++博客-天下-随笔分类-C++模板</title><link>http://www.cppblog.com/aaxron/category/20576.html</link><description>记录修行的印记
</description><language>zh-cn</language><lastBuildDate>Wed, 19 Oct 2016 05:46:31 GMT</lastBuildDate><pubDate>Wed, 19 Oct 2016 05:46:31 GMT</pubDate><ttl>60</ttl><item><title>c++ traits(1)</title><link>http://www.cppblog.com/aaxron/archive/2016/10/14/214333.html</link><dc:creator>天下</dc:creator><author>天下</author><pubDate>Fri, 14 Oct 2016 06:18:00 GMT</pubDate><guid>http://www.cppblog.com/aaxron/archive/2016/10/14/214333.html</guid><wfw:comment>http://www.cppblog.com/aaxron/comments/214333.html</wfw:comment><comments>http://www.cppblog.com/aaxron/archive/2016/10/14/214333.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/aaxron/comments/commentRss/214333.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/aaxron/services/trackbacks/214333.html</trackback:ping><description><![CDATA[<div style="font-size: 13px; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; width: 98%; border-bottom: #cccccc 1px solid; word-break: break-all; padding-bottom: 4px; padding-top: 4px; padding-left: 4px; border-left: #cccccc 1px solid; padding-right: 5px; background-color: #eeeeee"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #000000">#pragma&nbsp;once<br />template&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">typename&nbsp;T</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;&nbsp;<br /></span><span style="color: #0000ff">struct</span><span style="color: #000000">&nbsp;TraitsHelper;<br /><br />template&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">typename&nbsp;T</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;&nbsp;<br /></span><span style="color: #0000ff">struct</span><span style="color: #000000">&nbsp;TraitsHelper&nbsp;{&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">static</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">const</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">bool</span><span style="color: #000000">&nbsp;isPointer&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">false</span><span style="color: #000000">;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">enum</span><span style="color: #000000">&nbsp;{IsPointer&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">false</span><span style="color: #000000">};<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">bool</span><span style="color: #000000">&nbsp;GetIsPointer()<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;IsPointer;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />};&nbsp;&nbsp;<br />template&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">typename&nbsp;T</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;&nbsp;<br /></span><span style="color: #0000ff">struct</span><span style="color: #000000">&nbsp;TraitsHelper</span><span style="color: #000000">&lt;</span><span style="color: #000000">T</span><span style="color: #000000">*&gt;</span><span style="color: #000000">&nbsp;{&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">static</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">const</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">bool</span><span style="color: #000000">&nbsp;isPointer&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">true</span><span style="color: #000000">;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">enum</span><span style="color: #000000">&nbsp;{IsPointer&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">true</span><span style="color: #000000">};<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">bool</span><span style="color: #000000">&nbsp;GetIsPointer()<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;IsPointer;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />};&nbsp;&nbsp;<br /><br /></span><span style="color: #008000">//</span><span style="color: #008000">call</span><span style="color: #008000"><br /></span><span style="color: #000000">#include&nbsp;</span><span style="color: #000000">"</span><span style="color: #000000">stdafx.h</span><span style="color: #000000">"</span><span style="color: #000000"><br /></span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;_tmain(</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;argc,&nbsp;_TCHAR</span><span style="color: #000000">*</span><span style="color: #000000">&nbsp;argv[])<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;val&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">0</span><span style="color: #000000">;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">*</span><span style="color: #000000">&nbsp;pVal&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">&amp;</span><span style="color: #000000">val;<br />&nbsp;&nbsp;&nbsp;&nbsp;TraitsHelper</span><span style="color: #000000">&lt;</span><span style="color: #0000ff">int</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;a;<br />&nbsp;&nbsp;&nbsp;&nbsp;TraitsHelper</span><span style="color: #000000">&lt;</span><span style="color: #0000ff">int</span><span style="color: #000000">*&gt;</span><span style="color: #000000">&nbsp;b;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">bool</span><span style="color: #000000">&nbsp;b1&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;a.IsPointer;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">bool</span><span style="color: #000000">&nbsp;b2&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;b.IsPointer;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">bool</span><span style="color: #000000">&nbsp;b3&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;a.GetIsPointer();<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">bool</span><span style="color: #000000">&nbsp;b4&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;TraitsHelper</span><span style="color: #000000">&lt;</span><span style="color: #0000ff">int</span><span style="color: #000000">&gt;</span><span style="color: #000000">::IsPointer;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">bool</span><span style="color: #000000">&nbsp;b5&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;TraitsHelper</span><span style="color: #000000">&lt;</span><span style="color: #0000ff">int</span><span style="color: #000000">*&gt;</span><span style="color: #000000">::IsPointer;<br /><br /><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">0</span><span style="color: #000000">;<br />}</span></div><img src ="http://www.cppblog.com/aaxron/aggbug/214333.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/aaxron/" target="_blank">天下</a> 2016-10-14 14:18 <a href="http://www.cppblog.com/aaxron/archive/2016/10/14/214333.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[原创]一个C++异常的代替方案</title><link>http://www.cppblog.com/aaxron/archive/2015/08/21/211640.html</link><dc:creator>天下</dc:creator><author>天下</author><pubDate>Fri, 21 Aug 2015 07:34:00 GMT</pubDate><guid>http://www.cppblog.com/aaxron/archive/2015/08/21/211640.html</guid><wfw:comment>http://www.cppblog.com/aaxron/comments/211640.html</wfw:comment><comments>http://www.cppblog.com/aaxron/archive/2015/08/21/211640.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/aaxron/comments/commentRss/211640.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/aaxron/services/trackbacks/211640.html</trackback:ping><description><![CDATA[<div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; width: 98%; word-break: break-all;"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->#include&nbsp;"stdafx.h"<br /><br />template&nbsp;&lt;typename&nbsp;T&gt;<br /><span style="color: #0000FF; ">class</span>&nbsp;E<br />{<br /><span style="color: #0000FF; ">public</span>:<br />&nbsp;&nbsp;&nbsp;&nbsp;T&nbsp;val;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;errcode;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;E(){}<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;E(<span style="color: #0000FF; ">const</span>&nbsp;T&amp;&nbsp;val)<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;val&nbsp;=&nbsp;val;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">operator</span>&nbsp;T()&nbsp;<span style="color: #0000FF; ">const</span>&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;val;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">operator</span>&nbsp;T*()&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;&amp;val;<br />&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;E&lt;T&gt;&nbsp;<span style="color: #0000FF; ">operator</span>=(<span style="color: #0000FF; ">const</span>&nbsp;T&amp;&nbsp;_val)<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;val&nbsp;=&nbsp;_val;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;*<span style="color: #0000FF; ">this</span>;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br /><span style="color: #0000FF; ">public</span>:<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;fail()&nbsp;<span style="color: #0000FF; ">const</span><br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;errcode;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br />};<br /><br /><br />E&lt;<span style="color: #0000FF; ">int</span>&gt;&nbsp;GetResult(<span style="color: #0000FF; ">bool</span>&nbsp;fail)<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;E&lt;<span style="color: #0000FF; ">int</span>&gt;&nbsp;obj;<br />&nbsp;&nbsp;&nbsp;&nbsp;obj.val&nbsp;=&nbsp;0x1000;<br />&nbsp;&nbsp;&nbsp;&nbsp;obj.errcode&nbsp;=&nbsp;fail;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;obj;<br />}<br /><br /><br /><span style="color: #0000FF; ">int</span>&nbsp;_tmain(<span style="color: #0000FF; ">int</span>&nbsp;argc,&nbsp;_TCHAR*&nbsp;argv[])<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;E&lt;<span style="color: #0000FF; ">int</span>&gt;&nbsp;a;<br />&nbsp;&nbsp;&nbsp;&nbsp;a.val&nbsp;=&nbsp;5;<br />&nbsp;&nbsp;&nbsp;&nbsp;a.errcode&nbsp;=&nbsp;<span style="color: #0000FF; ">false</span>;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;b&nbsp;=&nbsp;a;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>*&nbsp;c&nbsp;=&nbsp;a;<br />&nbsp;&nbsp;&nbsp;&nbsp;*c&nbsp;=&nbsp;7;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">const</span>&nbsp;<span style="color: #0000FF; ">int</span>*&nbsp;d&nbsp;=&nbsp;a;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;e&nbsp;=&nbsp;a&nbsp;=&nbsp;8;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;E&lt;<span style="color: #0000FF; ">int</span>&gt;&nbsp;x&nbsp;=&nbsp;GetResult(<span style="color: #0000FF; ">true</span>);<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(x.fail())<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf("error&nbsp;\r\n");<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">else</span><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf("succeed&nbsp;\r\n");<br />&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(a.fail())<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf("error&nbsp;\r\n");<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;0;<br />}</div></div><img src ="http://www.cppblog.com/aaxron/aggbug/211640.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/aaxron/" target="_blank">天下</a> 2015-08-21 15:34 <a href="http://www.cppblog.com/aaxron/archive/2015/08/21/211640.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>MapStream</title><link>http://www.cppblog.com/aaxron/archive/2014/04/07/206493.html</link><dc:creator>天下</dc:creator><author>天下</author><pubDate>Mon, 07 Apr 2014 05:52:00 GMT</pubDate><guid>http://www.cppblog.com/aaxron/archive/2014/04/07/206493.html</guid><wfw:comment>http://www.cppblog.com/aaxron/comments/206493.html</wfw:comment><comments>http://www.cppblog.com/aaxron/archive/2014/04/07/206493.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/aaxron/comments/commentRss/206493.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/aaxron/services/trackbacks/206493.html</trackback:ping><description><![CDATA[<div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 4px; background-color: #eeeeee; padding-left: 4px; width: 98%; padding-right: 5px; font-size: 13px; word-break: break-all; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 4px"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #000000">#pragma&nbsp;once<br />#include&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">map</span><span style="color: #000000">&gt;</span><span style="color: #000000"><br />#include&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">cstdio</span><span style="color: #000000">&gt;</span><span style="color: #000000"><br /><br />#ifdef&nbsp;_WIN32<br />&nbsp;&nbsp;&nbsp;&nbsp;#include&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">sys</span><span style="color: #000000">/</span><span style="color: #000000">stat.h</span><span style="color: #000000">&gt;</span><span style="color: #000000"><br /></span><span style="color: #0000ff">#else</span><span style="color: #000000"><br /></span><span style="color: #0000ff">#endif</span><span style="color: #000000"><br /><br />template</span><span style="color: #000000">&lt;</span><span style="color: #000000">typename&nbsp;Key,typename&nbsp;Value</span><span style="color: #000000">&gt;</span><span style="color: #000000"><br /></span><span style="color: #0000ff">class</span><span style="color: #000000">&nbsp;MapStream<br />{<br /></span><span style="color: #0000ff">public</span><span style="color: #000000">:&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;std::map</span><span style="color: #000000">&lt;</span><span style="color: #000000">Key,Value</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;m_mapTable;<br />&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;typename&nbsp;std::map</span><span style="color: #000000">&lt;</span><span style="color: #000000">Key,Value</span><span style="color: #000000">&gt;</span><span style="color: #000000">::iterator&nbsp;MapStreamIterator;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;GetFileSize(</span><span style="color: #0000ff">const</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">char</span><span style="color: #000000">*</span><span style="color: #000000">&nbsp;filename)<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">struct</span><span style="color: #000000">&nbsp;stat&nbsp;f_stat;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">&nbsp;(stat(filename,&nbsp;</span><span style="color: #000000">&amp;</span><span style="color: #000000">f_stat)&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;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">-</span><span style="color: #000000">1</span><span style="color: #000000">;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;f_stat.st_size;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">bool</span><span style="color: #000000">&nbsp;Load(</span><span style="color: #0000ff">const</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">char</span><span style="color: #000000">*</span><span style="color: #000000">&nbsp;filename)<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FILE</span><span style="color: #000000">*</span><span style="color: #000000">&nbsp;fp&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;fopen(filename,</span><span style="color: #000000">"</span><span style="color: #000000">rb</span><span style="color: #000000">"</span><span style="color: #000000">);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">&nbsp;(fp&nbsp;</span><span style="color: #000000">==</span><span style="color: #000000">NULL)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">false</span><span style="color: #000000">;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;metasize&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">sizeof</span><span style="color: #000000">(Key)&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">sizeof</span><span style="color: #000000">(Value);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">char</span><span style="color: #000000">&nbsp;buffer[</span><span style="color: #0000ff">sizeof</span><span style="color: #000000">(Key)&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">sizeof</span><span style="color: #000000">(Value)];<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;&nbsp;readed;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Key</span><span style="color: #000000">*</span><span style="color: #000000">&nbsp;_key;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Value</span><span style="color: #000000">*</span><span style="color: #000000">&nbsp;_value;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;m_mapTable.clear();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">while</span><span style="color: #000000">&nbsp;(fread(buffer,</span><span style="color: #000000">1</span><span style="color: #000000">,metasize,fp)</span><span style="color: #000000">==</span><span style="color: #000000">metasize)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_key&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;(Key</span><span style="color: #000000">*</span><span style="color: #000000">)buffer;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_value&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;(Value</span><span style="color: #000000">*</span><span style="color: #000000">)</span><span style="color: #000000">&amp;</span><span style="color: #000000">buffer[</span><span style="color: #0000ff">sizeof</span><span style="color: #000000">(Key)];<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;m_mapTable[</span><span style="color: #000000">*</span><span style="color: #000000">_key]&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">*</span><span style="color: #000000">_value;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fclose(fp);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;(GetFileSize(filename)&nbsp;</span><span style="color: #000000">==</span><span style="color: #000000">&nbsp;(m_mapTable.size()</span><span style="color: #000000">*</span><span style="color: #000000">metasize));<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">bool</span><span style="color: #000000">&nbsp;Save(</span><span style="color: #0000ff">const</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">char</span><span style="color: #000000">*</span><span style="color: #000000">&nbsp;filename)<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FILE</span><span style="color: #000000">*</span><span style="color: #000000">&nbsp;fp&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;fopen(filename,</span><span style="color: #000000">"</span><span style="color: #000000">wb</span><span style="color: #000000">"</span><span style="color: #000000">);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">&nbsp;(fp&nbsp;</span><span style="color: #000000">==</span><span style="color: #000000">NULL)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">false</span><span style="color: #000000">;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;metasize&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">sizeof</span><span style="color: #000000">(Key)&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">sizeof</span><span style="color: #000000">(Value);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">char</span><span style="color: #000000">&nbsp;buffer[</span><span style="color: #0000ff">sizeof</span><span style="color: #000000">(Key)&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">sizeof</span><span style="color: #000000">(Value)];<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;&nbsp;readed;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Key</span><span style="color: #000000">*</span><span style="color: #000000">&nbsp;_key;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Value</span><span style="color: #000000">*</span><span style="color: #000000">&nbsp;_value;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MapStreamIterator&nbsp;iter&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;m_mapTable.begin();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">while</span><span style="color: #000000">&nbsp;(iter</span><span style="color: #000000">!=</span><span style="color: #000000">m_mapTable.end())<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fwrite(</span><span style="color: #000000">&amp;</span><span style="color: #000000">iter</span><span style="color: #000000">-&gt;</span><span style="color: #000000">first,&nbsp;</span><span style="color: #000000">1</span><span style="color: #000000">,</span><span style="color: #0000ff">sizeof</span><span style="color: #000000">(Key),fp);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fwrite(</span><span style="color: #000000">&amp;</span><span style="color: #000000">iter</span><span style="color: #000000">-&gt;</span><span style="color: #000000">second,</span><span style="color: #000000">1</span><span style="color: #000000">,</span><span style="color: #0000ff">sizeof</span><span style="color: #000000">(Value),fp);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;iter</span><span style="color: #000000">++</span><span style="color: #000000">;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fclose(fp);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;filesize&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;GetFileSize(filename);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;(GetFileSize(filename)&nbsp;</span><span style="color: #000000">==</span><span style="color: #000000">&nbsp;(m_mapTable.size()</span><span style="color: #000000">*</span><span style="color: #000000">metasize));<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;Value</span><span style="color: #000000">&amp;</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">operator</span><span style="color: #000000">[]&nbsp;(</span><span style="color: #0000ff">const</span><span style="color: #000000">&nbsp;Key</span><span style="color: #000000">&amp;</span><span style="color: #000000">&nbsp;_key)<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;m_mapTable[_key];<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;Value</span><span style="color: #000000">*</span><span style="color: #000000">&nbsp;GetValue(</span><span style="color: #0000ff">const</span><span style="color: #000000">&nbsp;Key</span><span style="color: #000000">&amp;</span><span style="color: #000000">&nbsp;_key)<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MapStreamIterator&nbsp;iter&nbsp;&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;m_mapTable.find(_key);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">&nbsp;(iter</span><span style="color: #000000">!=</span><span style="color: #000000">m_mapTable.end())<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">&amp;</span><span style="color: #000000">iter</span><span style="color: #000000">-&gt;</span><span style="color: #000000">second;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;NULL;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">void</span><span style="color: #000000">&nbsp;SetValue(</span><span style="color: #0000ff">const</span><span style="color: #000000">&nbsp;Key</span><span style="color: #000000">&amp;</span><span style="color: #000000">&nbsp;_key,</span><span style="color: #0000ff">const</span><span style="color: #000000">&nbsp;Value</span><span style="color: #000000">&amp;</span><span style="color: #000000">&nbsp;_value)<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;m_mapTable[_key]&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;_value;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">void</span><span style="color: #000000">&nbsp;RemoveKey(</span><span style="color: #0000ff">const</span><span style="color: #000000">&nbsp;Key</span><span style="color: #000000">&amp;</span><span style="color: #000000">&nbsp;_key)<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;m_mapTable.erase(_key);<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;Count()<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;m_mapTable.size();<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />};</span></div><img src ="http://www.cppblog.com/aaxron/aggbug/206493.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/aaxron/" target="_blank">天下</a> 2014-04-07 13:52 <a href="http://www.cppblog.com/aaxron/archive/2014/04/07/206493.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C++类中模板函数的特化</title><link>http://www.cppblog.com/aaxron/archive/2013/06/26/201317.html</link><dc:creator>天下</dc:creator><author>天下</author><pubDate>Wed, 26 Jun 2013 03:51:00 GMT</pubDate><guid>http://www.cppblog.com/aaxron/archive/2013/06/26/201317.html</guid><wfw:comment>http://www.cppblog.com/aaxron/comments/201317.html</wfw:comment><comments>http://www.cppblog.com/aaxron/archive/2013/06/26/201317.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/aaxron/comments/commentRss/201317.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/aaxron/services/trackbacks/201317.html</trackback:ping><description><![CDATA[<div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 4px; background-color: #eeeeee; padding-left: 4px; width: 98%; padding-right: 5px; font-size: 13px; word-break: break-all; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 4px"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #000000">C</span><span style="color: #000000">++</span><span style="color: #000000">类中模板函数的特化<br /><br /></span><span style="color: #000000">最近在使用在使用模板特化&nbsp;写一段程序时发现一个奇怪的问题，比如像如下代码：<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#include&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">iostream</span><span style="color: #000000">&gt;</span><span style="color: #000000"><br /></span><span style="color: #0000ff">using</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">namespace</span><span style="color: #000000">&nbsp;std;<br /></span><span style="color: #0000ff">class</span><span style="color: #000000">&nbsp;CMyClass<br />{<br /></span><span style="color: #0000ff">public</span><span style="color: #000000">:<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;template&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">typename&nbsp;T</span><span style="color: #000000">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">struct</span><span style="color: #000000">&nbsp;test<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;T&nbsp;i;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;};<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;template&nbsp;</span><span style="color: #000000">&lt;&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">struct</span><span style="color: #000000">&nbsp;test</span><span style="color: #000000">&lt;</span><span style="color: #0000ff">long</span><span style="color: #000000">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;</span><span style="color: #0000ff">long</span><span style="color: #000000">&nbsp;i;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;};<br />};<br /><br /></span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;main(</span><span style="color: #0000ff">void</span><span style="color: #000000">)<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CMyClass::test</span><span style="color: #000000">&lt;</span><span style="color: #0000ff">int</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;test1;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CMyClass::test</span><span style="color: #000000">&lt;</span><span style="color: #0000ff">long</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;test2;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CMyClass::test</span><span style="color: #000000">&lt;</span><span style="color: #0000ff">char</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;test3;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cout&nbsp;</span><span style="color: #000000">&lt;&lt;</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">"</span><span style="color: #000000">typeid(test1.i)&nbsp;is&nbsp;</span><span style="color: #000000">"</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">&lt;&lt;</span><span style="color: #000000">&nbsp;typeid(test1.i).name()&nbsp;</span><span style="color: #000000">&lt;&lt;</span><span style="color: #000000">&nbsp;endl;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cout&nbsp;</span><span style="color: #000000">&lt;&lt;</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">"</span><span style="color: #000000">typeid(test2.i)&nbsp;is&nbsp;</span><span style="color: #000000">"</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">&lt;&lt;</span><span style="color: #000000">&nbsp;typeid(test2.i).name()&nbsp;</span><span style="color: #000000">&lt;&lt;</span><span style="color: #000000">&nbsp;endl;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cout&nbsp;</span><span style="color: #000000">&lt;&lt;</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">"</span><span style="color: #000000">typeid(test3.i)&nbsp;is&nbsp;</span><span style="color: #000000">"</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">&lt;&lt;</span><span style="color: #000000">&nbsp;typeid(test3.i).name()&nbsp;</span><span style="color: #000000">&lt;&lt;</span><span style="color: #000000">&nbsp;endl;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">0</span><span style="color: #000000">;<br />}<br /><br />这段代码在Linux下的GCC&nbsp;</span><span style="color: #000000">3.4</span><span style="color: #000000">.3下无法编译通过，编译时提示错误：<br /><br />xxx.cpp:</span><span style="color: #000000">12</span><span style="color: #000000">:&nbsp;error:&nbsp;invalid&nbsp;</span><span style="color: #0000ff">explicit</span><span style="color: #000000">&nbsp;specialization&nbsp;before&nbsp;</span><span style="color: #000000">'</span><span style="color: #000000">&gt;</span><span style="color: #000000">'</span><span style="color: #000000">&nbsp;token<br />xxx.cpp:</span><span style="color: #000000">12</span><span style="color: #000000">:&nbsp;error:&nbsp;</span><span style="color: #0000ff">explicit</span><span style="color: #000000">&nbsp;specialization&nbsp;</span><span style="color: #0000ff">in</span><span style="color: #000000">&nbsp;non</span><span style="color: #000000">-</span><span style="color: #0000ff">namespace</span><span style="color: #000000">&nbsp;scope&nbsp;`</span><span style="color: #0000ff">class</span><span style="color: #000000">&nbsp;CMyClass</span><span style="color: #000000">'<br /></span><span style="color: #000000"><br />但在VC6和VC8下都可以编译通过。<br /><br />&nbsp;<br /><br />后翻阅资料，发现有人提到，C</span><span style="color: #000000">++</span><span style="color: #000000">标准中规定，嵌套类模板在类的定义中不允许被显示特化声明，只允许偏特化（&#8220;Explicit&nbsp;template&nbsp;specialization&nbsp;</span><span style="color: #0000ff">is</span><span style="color: #000000">&nbsp;forbidden&nbsp;</span><span style="color: #0000ff">for</span><span style="color: #000000">&nbsp;nested&nbsp;classes&nbsp;&#8221;，&#8220;As&nbsp;partial&nbsp;template&nbsp;specialization&nbsp;</span><span style="color: #0000ff">is</span><span style="color: #000000">&nbsp;not&nbsp;forbidden&nbsp;&#8221;），比如，这样就可以：<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />#include&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">iostream</span><span style="color: #000000">&gt;</span><span style="color: #000000"><br /></span><span style="color: #0000ff">using</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">namespace</span><span style="color: #000000">&nbsp;std;<br /><br /></span><span style="color: #0000ff">class</span><span style="color: #000000">&nbsp;CMyClass<br />{<br /></span><span style="color: #0000ff">public</span><span style="color: #000000">:<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;template&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">typename&nbsp;T,&nbsp;typename&nbsp;S&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">void</span><span style="color: #000000">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">struct</span><span style="color: #000000">&nbsp;test<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;T&nbsp;i;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;};<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;template&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">typename&nbsp;S</span><span style="color: #000000">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">struct</span><span style="color: #000000">&nbsp;test</span><span style="color: #000000">&lt;</span><span style="color: #0000ff">long</span><span style="color: #000000">,&nbsp;S</span><span style="color: #000000">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;</span><span style="color: #0000ff">long</span><span style="color: #000000">&nbsp;i;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;};<br />};<br /></span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;main(</span><span style="color: #0000ff">void</span><span style="color: #000000">)<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CMyClass::test</span><span style="color: #000000">&lt;</span><span style="color: #0000ff">int</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;test1;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CMyClass::test</span><span style="color: #000000">&lt;</span><span style="color: #0000ff">long</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;test2;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CMyClass::test</span><span style="color: #000000">&lt;</span><span style="color: #0000ff">char</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;test3;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cout&nbsp;</span><span style="color: #000000">&lt;&lt;</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">"</span><span style="color: #000000">typeid(test1.i)&nbsp;is&nbsp;</span><span style="color: #000000">"</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">&lt;&lt;</span><span style="color: #000000">&nbsp;typeid(test1.i).name()&nbsp;</span><span style="color: #000000">&lt;&lt;</span><span style="color: #000000">&nbsp;endl;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cout&nbsp;</span><span style="color: #000000">&lt;&lt;</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">"</span><span style="color: #000000">typeid(test2.i)&nbsp;is&nbsp;</span><span style="color: #000000">"</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">&lt;&lt;</span><span style="color: #000000">&nbsp;typeid(test2.i).name()&nbsp;</span><span style="color: #000000">&lt;&lt;</span><span style="color: #000000">&nbsp;endl;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cout&nbsp;</span><span style="color: #000000">&lt;&lt;</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">"</span><span style="color: #000000">typeid(test3.i)&nbsp;is&nbsp;</span><span style="color: #000000">"</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">&lt;&lt;</span><span style="color: #000000">&nbsp;typeid(test3.i).name()&nbsp;</span><span style="color: #000000">&lt;&lt;</span><span style="color: #000000">&nbsp;endl;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">0</span><span style="color: #000000">;<br /><br />}<br /><br />在上面这段代码使用一个无用的模板参数来实现以偏特代替特化，从而化解了这个问题。至于为什么VC下能够正常编译，网上的资料说是VC不符合标准&nbsp;（&#8220;MSVC&nbsp;</span><span style="color: #0000ff">is</span><span style="color: #000000">&nbsp;wrong&nbsp;</span><span style="color: #0000ff">in</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">this</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">case</span><span style="color: #000000">&nbsp;and&nbsp;g</span><span style="color: #000000">++</span><span style="color: #000000">&nbsp;correct&#8221;），不过这点我尚未在C</span><span style="color: #000000">++</span><span style="color: #000000">标准中找到明文依据。<br /><br />但是这样一来就有个问题，偏特化在VC6下是用BUG的，无法正常使用，也就是说出来的代码将无法兼容VC6。对于VC6这样落伍的编译器，兼容它&nbsp;是没有太大的必要，但是回头想想，难道要在定义嵌套类模板的特化，就不行了么？必须使用偏特化来代替么？C</span><span style="color: #000000">++</span><span style="color: #000000">对此是如何规定的呢？翻阅相关资料后，我找&nbsp;到了答案－－要把特化的代码写在类定义的外面（要写在namespace下），如第一段代码应该写成这样：<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />#include&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">iostream</span><span style="color: #000000">&gt;</span><span style="color: #000000"><br /></span><span style="color: #0000ff">using</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">namespace</span><span style="color: #000000">&nbsp;std;<br /><br /></span><span style="color: #0000ff">class</span><span style="color: #000000">&nbsp;CMyClass<br />{<br /></span><span style="color: #0000ff">public</span><span style="color: #000000">:<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;template&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">typename&nbsp;T</span><span style="color: #000000">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">struct</span><span style="color: #000000">&nbsp;test<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;i;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;};<br />};<br />template&nbsp;</span><span style="color: #000000">&lt;&gt;</span><span style="color: #000000"><br /></span><span style="color: #0000ff">struct</span><span style="color: #000000">&nbsp;CMyClass::test</span><span style="color: #000000">&lt;</span><span style="color: #0000ff">long</span><span style="color: #000000">&gt;</span><span style="color: #000000"><br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">long</span><span style="color: #000000">&nbsp;i;<br />};<br /><br /></span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;main(</span><span style="color: #0000ff">void</span><span style="color: #000000">)<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CMyClass::test</span><span style="color: #000000">&lt;</span><span style="color: #0000ff">int</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;test1;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CMyClass::test</span><span style="color: #000000">&lt;</span><span style="color: #0000ff">long</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;test2;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CMyClass::test</span><span style="color: #000000">&lt;</span><span style="color: #0000ff">char</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;test3;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cout&nbsp;</span><span style="color: #000000">&lt;&lt;</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">"</span><span style="color: #000000">typeid(test1.i)&nbsp;is&nbsp;</span><span style="color: #000000">"</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">&lt;&lt;</span><span style="color: #000000">&nbsp;typeid(test1.i).name()&nbsp;</span><span style="color: #000000">&lt;&lt;</span><span style="color: #000000">&nbsp;endl;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cout&nbsp;</span><span style="color: #000000">&lt;&lt;</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">"</span><span style="color: #000000">typeid(test2.i)&nbsp;is&nbsp;</span><span style="color: #000000">"</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">&lt;&lt;</span><span style="color: #000000">&nbsp;typeid(test2.i).name()&nbsp;</span><span style="color: #000000">&lt;&lt;</span><span style="color: #000000">&nbsp;endl;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cout&nbsp;</span><span style="color: #000000">&lt;&lt;</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">"</span><span style="color: #000000">typeid(test3.i)&nbsp;is&nbsp;</span><span style="color: #000000">"</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">&lt;&lt;</span><span style="color: #000000">&nbsp;typeid(test3.i).name()&nbsp;</span><span style="color: #000000">&lt;&lt;</span><span style="color: #000000">&nbsp;endl;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">0</span><span style="color: #000000">;<br />}<br /><br />这样修改后，就可以在GCC下编译通过了，同时，VC6，VC8也都能编译通过！<br /><br />总结一下吧：<br />在C</span><span style="color: #000000">++</span><span style="color: #000000">中，如果要对嵌套类模板进行特化，则要么使用偏特化来替代特化（增加一个无用的模板参数），要么将&nbsp;特化代码放在类定义之外。<br /><br />同样的,非模板函数具有最高的优先权<br /></span></div><br /><br /><br /><br />转自:<a href="http://jeffreyloo.blog.163.com/blog/static/12176167020106171424608/">http://jeffreyloo.blog.163.com/blog/static/12176167020106171424608/</a> <img src ="http://www.cppblog.com/aaxron/aggbug/201317.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/aaxron/" target="_blank">天下</a> 2013-06-26 11:51 <a href="http://www.cppblog.com/aaxron/archive/2013/06/26/201317.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>模板特化和偏特化</title><link>http://www.cppblog.com/aaxron/archive/2013/06/26/201316.html</link><dc:creator>天下</dc:creator><author>天下</author><pubDate>Wed, 26 Jun 2013 03:38:00 GMT</pubDate><guid>http://www.cppblog.com/aaxron/archive/2013/06/26/201316.html</guid><wfw:comment>http://www.cppblog.com/aaxron/comments/201316.html</wfw:comment><comments>http://www.cppblog.com/aaxron/archive/2013/06/26/201316.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/aaxron/comments/commentRss/201316.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/aaxron/services/trackbacks/201316.html</trackback:ping><description><![CDATA[<div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 4px; background-color: #eeeeee; padding-left: 4px; width: 98%; padding-right: 5px; font-size: 13px; word-break: break-all; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 4px"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #000000">模板特化和偏特化<br />C</span><span style="color: #000000">++</span><span style="color: #000000">中的模板分为类模板和函数模板<br /><br />&#183;模板的特化<br />&nbsp;&nbsp;&nbsp;&nbsp;<br />(</span><span style="color: #000000">1</span><span style="color: #000000">)类模板特化<br />有时为了需要,针对特定的类型,需要对模板进行特化,也就是特殊处理.例如,stack类模板针对bool类型,因为实际上bool类型只需要一个二进制位，就可以对其进行存储,使用一个字或者一个字节都是浪费存储空间的.<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">class</span><span style="color: #000000">&nbsp;stack&nbsp;{};<br /><br />template</span><span style="color: #000000">&lt;&gt;</span><span style="color: #000000"><br /></span><span style="color: #0000ff">class</span><span style="color: #000000">&nbsp;stack</span><span style="color: #000000">&lt;</span><span style="color: #0000ff">bool</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;<br />{&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&#8230;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;</span><span style="color: #008000"><br /></span><span style="color: #000000">};<br /><br />上述定义中template&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">&gt;</span><span style="color: #000000">告诉编译器这是一个特化的模板。并且在声明特化模板之前一定要有非特化的声明！并且两个类的名字是一样的！<br />&nbsp;&nbsp;&nbsp;&nbsp;<br />(</span><span style="color: #000000">2</span><span style="color: #000000">)函数模板的特化<br />看下面的例子<br /></span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;main()<br />{<br />&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;highest&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;mymax(</span><span style="color: #000000">5</span><span style="color: #000000">,</span><span style="color: #000000">10</span><span style="color: #000000">);<br />&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">char</span><span style="color: #000000">&nbsp;c&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;mymax(&#8216;a&#8217;,&nbsp;&#8217;z&#8217;);<br />&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">const</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">char</span><span style="color: #000000">*</span><span style="color: #000000">&nbsp;p1&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;&#8220;hello&#8221;;<br />&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">const</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">char</span><span style="color: #000000">*</span><span style="color: #000000">&nbsp;p2&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;&#8220;world&#8221;;<br />&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">const</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">char</span><span style="color: #000000">*</span><span style="color: #000000">&nbsp;p&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;mymax(p1,p2);<br />&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">0</span><span style="color: #000000">;<br />}<br />前面两个mymax都能返回正确的结果.而第三个却不能,因为,此时mymax直接比较两个指针p1&nbsp;和&nbsp;p2&nbsp;而不是其指向的内容.<br />针对这种情况,当mymax函数的参数类型为const&nbsp;</span><span style="color: #0000ff">char</span><span style="color: #000000">*</span><span style="color: #000000">&nbsp;时,需要特化。<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 />T&nbsp;mymax(</span><span style="color: #0000ff">const</span><span style="color: #000000">&nbsp;T&nbsp;t1,&nbsp;</span><span style="color: #0000ff">const</span><span style="color: #000000">&nbsp;T&nbsp;t2)<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;t1&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">&nbsp;t2&nbsp;</span><span style="color: #000000">?</span><span style="color: #000000">&nbsp;t2&nbsp;:&nbsp;t1;<br />}<br />template&nbsp;</span><span style="color: #000000">&lt;&gt;</span><span style="color: #000000"><br /></span><span style="color: #0000ff">const</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">char</span><span style="color: #000000">*</span><span style="color: #000000">&nbsp;mymax(</span><span style="color: #0000ff">const</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">char</span><span style="color: #000000">*</span><span style="color: #000000">&nbsp;t1,</span><span style="color: #0000ff">const</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">char</span><span style="color: #000000">*</span><span style="color: #000000">&nbsp;t2)<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;(strcmp(t1,t2)&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">0</span><span style="color: #000000">)&nbsp;</span><span style="color: #000000">?</span><span style="color: #000000">&nbsp;t2&nbsp;:&nbsp;t1;<br />}<br />现在mymax(p1,p2)能够返回正确的结果了。<br /><br /></span><span style="color: #000000">4</span><span style="color: #000000">.模板的偏特化<br />模板的偏特化是指需要根据模板的某些但不是全部的参数进行特化<br />(</span><span style="color: #000000">1</span><span style="color: #000000">)&nbsp;类模板的偏特化<br />例如c</span><span style="color: #000000">++</span><span style="color: #000000">标准库中的类vector的定义<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;Allocator</span><span style="color: #000000">&gt;</span><span style="color: #000000"><br /></span><span style="color: #0000ff">class</span><span style="color: #000000">&nbsp;vector&nbsp;<br />{&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;&#8230;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;</span><span style="color: #008000"><br /></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;Allocator</span><span style="color: #000000">&gt;</span><span style="color: #000000"><br /></span><span style="color: #0000ff">class</span><span style="color: #000000">&nbsp;vector</span><span style="color: #000000">&lt;</span><span style="color: #0000ff">bool</span><span style="color: #000000">,&nbsp;Allocator</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;<br />{&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&#8230;</span><span style="color: #008000">//<br /></span><span style="color: #000000">};<br />这个偏特化的例子中，一个参数被绑定到bool类型，而另一个参数仍未绑定需要由用户指定。<br /><br />(</span><span style="color: #000000">2</span><span style="color: #000000">)&nbsp;函数模板的偏特化<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">void</span><span style="color: #000000">&nbsp;f(T);&nbsp;&nbsp;&nbsp;(a)<br />根据重载规则，对（a）进行重载<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</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">void</span><span style="color: #000000">&nbsp;f(T</span><span style="color: #000000">*</span><span style="color: #000000">);&nbsp;&nbsp;&nbsp;(b)<br />如果将（a）称为基模板，那么（b）称为对基模板（a）的重载，而非对（a）的偏特化。C</span><span style="color: #000000">++</span><span style="color: #000000">的标准委员会仍在对下一个版本中是否允许函数模板的偏特化进行讨论。<br /></span><span style="color: #000000">5</span><span style="color: #000000">.模板特化时的匹配规则<br />(</span><span style="color: #000000">1</span><span style="color: #000000">)&nbsp;类模板的匹配规则<br />最优化的优于次特化的，即模板参数最精确匹配的具有最高的优先权<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">class</span><span style="color: #000000">&nbsp;vector<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&#8230;</span><span style="color: #008000">//<br /></span><span style="color: #000000">};&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;(a)&nbsp;&nbsp;&nbsp;普通型</span><span style="color: #008000"><br /></span><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">&nbsp;</span><span style="color: #0000ff">class</span><span style="color: #000000">&nbsp;vector</span><span style="color: #000000">&lt;</span><span style="color: #000000">T</span><span style="color: #000000">*&gt;</span><span style="color: #000000"><br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&#8230;</span><span style="color: #008000">//<br /></span><span style="color: #000000">};&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;(b)&nbsp;对指针类型特化</span><span style="color: #008000"><br /></span><span style="color: #000000">template&nbsp;</span><span style="color: #000000">&lt;&gt;</span><span style="color: #000000"><br /></span><span style="color: #0000ff">class</span><span style="color: #000000">&nbsp;vector&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #0000ff">void</span><span style="color: #000000">*&gt;</span><span style="color: #000000"><br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&#8230;</span><span style="color: #008000">//<br /></span><span style="color: #000000">};&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;(c)&nbsp;对void*进行特化</span><span style="color: #008000"><br /></span><span style="color: #000000">每个类型都可以用作普通型（a）的参数，但只有指针类型才能用作（b）的参数，而只有void</span><span style="color: #000000">*</span><span style="color: #000000">才能作为(c)的参数<br /><br />(</span><span style="color: #000000">2</span><span style="color: #000000">)&nbsp;函数模板的匹配规则<br />非模板函数具有最高的优先权。如果不存在匹配的非模板函数的话，那么最匹配的和最特化的函数具有高优先权<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">void</span><span style="color: #000000">&nbsp;f(T);&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;(d)</span><span style="color: #008000"><br /></span><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">&nbsp;</span><span style="color: #0000ff">void</span><span style="color: #000000">&nbsp;f(</span><span style="color: #0000ff">int</span><span style="color: #000000">,&nbsp;T,&nbsp;</span><span style="color: #0000ff">double</span><span style="color: #000000">);&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;(e)</span><span style="color: #008000"><br /></span><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">&nbsp;</span><span style="color: #0000ff">void</span><span style="color: #000000">&nbsp;f(T</span><span style="color: #000000">*</span><span style="color: #000000">);&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;(f)</span><span style="color: #008000"><br /></span><span style="color: #000000">template&nbsp;</span><span style="color: #000000">&lt;&gt;</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">void</span><span style="color: #000000">&nbsp;f</span><span style="color: #000000">&lt;</span><span style="color: #0000ff">int</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;(</span><span style="color: #0000ff">int</span><span style="color: #000000">)&nbsp;;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;(g)</span><span style="color: #008000"><br /></span><span style="color: #0000ff">void</span><span style="color: #000000">&nbsp;f(</span><span style="color: #0000ff">double</span><span style="color: #000000">);&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;(h)</span><span style="color: #008000"><br /></span><span style="color: #0000ff">bool</span><span style="color: #000000">&nbsp;b;<br /></span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;i;<br /></span><span style="color: #0000ff">double</span><span style="color: #000000">&nbsp;d;<br />f(b);&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;以&nbsp;T&nbsp;=&nbsp;bool&nbsp;调用&nbsp;（d）</span><span style="color: #008000"><br /></span><span style="color: #000000">f(i,</span><span style="color: #000000">42</span><span style="color: #000000">,d)&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;以&nbsp;T&nbsp;=&nbsp;int&nbsp;调用（e）</span><span style="color: #008000"><br /></span><span style="color: #000000">f(</span><span style="color: #000000">&amp;</span><span style="color: #000000">i)&nbsp;;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;以&nbsp;T&nbsp;=&nbsp;int*&nbsp;调用（f）</span><span style="color: #008000"><br /></span><span style="color: #000000">f(d);&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;&nbsp;&nbsp;调用（h）</span></div> <img src ="http://www.cppblog.com/aaxron/aggbug/201316.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/aaxron/" target="_blank">天下</a> 2013-06-26 11:38 <a href="http://www.cppblog.com/aaxron/archive/2013/06/26/201316.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C++ 高级主题之模板特化</title><link>http://www.cppblog.com/aaxron/archive/2013/06/26/201314.html</link><dc:creator>天下</dc:creator><author>天下</author><pubDate>Wed, 26 Jun 2013 03:36:00 GMT</pubDate><guid>http://www.cppblog.com/aaxron/archive/2013/06/26/201314.html</guid><wfw:comment>http://www.cppblog.com/aaxron/comments/201314.html</wfw:comment><comments>http://www.cppblog.com/aaxron/archive/2013/06/26/201314.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/aaxron/comments/commentRss/201314.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/aaxron/services/trackbacks/201314.html</trackback:ping><description><![CDATA[<div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 4px; background-color: #eeeeee; padding-left: 4px; width: 98%; padding-right: 5px; font-size: 13px; word-break: break-all; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 4px"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #000000">C</span><span style="color: #000000">++</span><span style="color: #000000">&nbsp;高级主题之模板特化<br />我们很难写出所有可能被实例化的类型都合适的模板。某些情况下，通用模板定义对于某个类型可能是完全错误的，所以我们需要能够实现处理某些特殊情况，特化的概念变是如此。<br />compare函数和Queue类是这个问题的很好例子。因为与C风格字符串一起使用时，他们都不能正确工作。<br />template&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">typename&nbsp;T</span><span style="color: #000000">&gt;</span><span style="color: #000000"><br /></span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;compare(</span><span style="color: #0000ff">const</span><span style="color: #000000">&nbsp;T&nbsp;</span><span style="color: #000000">&amp;</span><span style="color: #000000">v1,</span><span style="color: #0000ff">const</span><span style="color: #000000">&nbsp;T&nbsp;</span><span style="color: #000000">&amp;</span><span style="color: #000000">v2)<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">(v1&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">&nbsp;v2)&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">-</span><span style="color: #000000">1</span><span style="color: #000000">;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">(v2&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">&nbsp;v1)&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">1</span><span style="color: #000000">;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">0</span><span style="color: #000000">;<br />}<br />如果用两个const&nbsp;</span><span style="color: #0000ff">char</span><span style="color: #000000">*</span><span style="color: #000000">&nbsp;实参调用这个模板定义，函数将比较指针的值。也就是比较两个指针在内存中的相对位置，却并没有说明与指针所指数组的内容有关的任何事情。<br />为了能够将compare函数用于字符串，必须提供一个知道怎样比较C风格字符串的特殊定义。这些就被称作是特化的，它对模板的用户而言是透明的。<br /><br /></span><span style="color: #000000">1</span><span style="color: #000000">.&nbsp;函数模板的特化<br />特化形式：<br /></span><span style="color: #000000">-</span><span style="color: #000000">&nbsp;关键字template后面接一对空的尖括号</span><span style="color: #000000">&lt;&gt;</span><span style="color: #000000">;<br /></span><span style="color: #000000">-</span><span style="color: #000000">&nbsp;再接模板名和一对尖括号</span><span style="color: #000000">&lt;&gt;</span><span style="color: #000000">，尖括号中指定这个特化定义的模板参数：<br /></span><span style="color: #000000">-</span><span style="color: #000000">&nbsp;函数形参表<br /></span><span style="color: #000000">-</span><span style="color: #000000">&nbsp;函数体<br />template</span><span style="color: #000000">&lt;&gt;</span><span style="color: #000000"><br /></span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;compare</span><span style="color: #000000">&lt;</span><span style="color: #0000ff">const</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">char</span><span style="color: #000000">*&gt;</span><span style="color: #000000">&nbsp;(</span><span style="color: #0000ff">const</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">char</span><span style="color: #000000">*</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">const</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">&amp;</span><span style="color: #000000">v1,</span><span style="color: #0000ff">const</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">char</span><span style="color: #000000">*</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">const</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">&amp;</span><span style="color: #000000">v2)<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;strcmp(v1,v2);<br />}<br />特化的声明必须与&nbsp;对应的模板相匹配。类型形参固定为const&nbsp;</span><span style="color: #0000ff">char</span><span style="color: #000000">*</span><span style="color: #000000">。<br />因此，函数形参是const&nbsp;</span><span style="color: #0000ff">char</span><span style="color: #000000">*</span><span style="color: #000000">&nbsp;的const引用。当调用compare函数的时候，<br />传给它两个字符指针，编译器将调用特化版本。而不调用上面的泛型版本。<br /></span><span style="color: #0000ff">const</span><span style="color: #000000">&nbsp;&nbsp;</span><span style="color: #0000ff">char</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">*</span><span style="color: #000000">cp1&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">"</span><span style="color: #000000">world</span><span style="color: #000000">"</span><span style="color: #000000">,&nbsp;</span><span style="color: #000000">*</span><span style="color: #000000">cp2&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">"</span><span style="color: #000000">hi</span><span style="color: #000000">"</span><span style="color: #000000">;<br /></span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;i1,&nbsp;i2;<br />compare(cp1,&nbsp;cp2);&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">调用特化函数模板</span><span style="color: #008000"><br /></span><span style="color: #000000">compare(i1,&nbsp;i2);&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">调用泛型函数模板</span><span style="color: #008000"><br /></span><span style="color: #000000">注意：<br /></span><span style="color: #000000">*</span><span style="color: #000000">&nbsp;函数模板特化时template</span><span style="color: #000000">&lt;&gt;</span><span style="color: #000000">不能省略，如果缺少结果是声明该函数的重载。<br /></span><span style="color: #000000">*</span><span style="color: #000000">&nbsp;必须包含函数形参列表。如果可以从形参列表推断模板实参，则不必显示指定模板实参。<br /></span><span style="color: #000000">*</span><span style="color: #000000">&nbsp;如果程序由多个文件构成，模板特化的声明必须在使用该特化的每个文件中出现。<br /><br /></span><span style="color: #000000">2</span><span style="color: #000000">.类模板的特化<br />当使用C风格字符串时，Queue类具有&nbsp;compare函数相似的问题。问题就处在push函数中，该函数复制给定的值以创建Queue中的新元素。默认情况下，复制C风格字符串只会复制指针，不会复制字符。而显然复制指针将出现一系列的严重问题。为了解决复制C风格字符串的问题，需要为const&nbsp;</span><span style="color: #0000ff">char</span><span style="color: #000000">*</span><span style="color: #000000">定义整个类的特化版本:<br />template</span><span style="color: #000000">&lt;&gt;</span><span style="color: #000000">&nbsp;<br /></span><span style="color: #0000ff">class</span><span style="color: #000000">&nbsp;Queue</span><span style="color: #000000">&lt;</span><span style="color: #0000ff">const</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">char</span><span style="color: #000000">*&gt;</span><span style="color: #000000">&nbsp;<br />{<br /></span><span style="color: #0000ff">public</span><span style="color: #000000">:<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">void</span><span style="color: #000000">&nbsp;push(</span><span style="color: #0000ff">const</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">char</span><span style="color: #000000">*</span><span style="color: #000000">);<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">void</span><span style="color: #000000">&nbsp;pop()&nbsp;{real_queue.pop();}<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">bool</span><span style="color: #000000">&nbsp;empty()&nbsp;</span><span style="color: #0000ff">const</span><span style="color: #000000">&nbsp;{</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;real_queue.front();}<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">返回类型与模板参数类型不同</span><span style="color: #008000"><br /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;std::</span><span style="color: #0000ff">string</span><span style="color: #000000">&nbsp;front()&nbsp;{</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;real_queue.front();}<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">const</span><span style="color: #000000">&nbsp;std::</span><span style="color: #0000ff">string</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">&amp;</span><span style="color: #000000">front()&nbsp;</span><span style="color: #0000ff">const</span><span style="color: #000000">&nbsp;{</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;real_queue.front();}<br /></span><span style="color: #0000ff">private</span><span style="color: #000000">&nbsp;:<br />&nbsp;&nbsp;&nbsp;&nbsp;Queue</span><span style="color: #000000">&lt;</span><span style="color: #000000">std::</span><span style="color: #0000ff">string</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;real_queue;<br />};<br /><br />给Queue一个新的数据元素,string对象的Queue。在类的外部定义一个成员:<br /></span><span style="color: #0000ff">void</span><span style="color: #000000">&nbsp;Queue</span><span style="color: #000000">&lt;</span><span style="color: #0000ff">const</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">char</span><span style="color: #000000">*&gt;</span><span style="color: #000000">::push&nbsp;(</span><span style="color: #0000ff">const</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">char</span><span style="color: #000000">*</span><span style="color: #000000">&nbsp;val)<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;real_queue.push(val);<br />}<br />这个函数通过调用read_queue的push函数把val指向的数组复制到未命名的string&nbsp;对象中。当需要出队列的时候调用相应real_queue.pop()函数即返回了这个string，从而解决了不用复制指针的问题。<br /><br /></span><span style="color: #000000">3</span><span style="color: #000000">.特化成员而不特化类在上例的实现中，我们可以换一种方法，即不需要特化类，而只需要特化类的成员函数push、pop。根据函数模板特化的要求：<br />template&nbsp;</span><span style="color: #000000">&lt;&gt;</span><span style="color: #000000"><br /></span><span style="color: #0000ff">void</span><span style="color: #000000">&nbsp;Queue</span><span style="color: #000000">&lt;</span><span style="color: #0000ff">const</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">char</span><span style="color: #000000">*&gt;</span><span style="color: #000000">::push(</span><span style="color: #0000ff">const</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">char</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">*</span><span style="color: #0000ff">const</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">&amp;</span><span style="color: #000000">val)<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">char</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">*</span><span style="color: #000000">&nbsp;new_item&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">char</span><span style="color: #000000">[strlen(val)</span><span style="color: #000000">+</span><span style="color: #000000">1</span><span style="color: #000000">];<br />&nbsp;&nbsp;&nbsp;&nbsp;strncpy(new_item,&nbsp;val,&nbsp;strlen(val)</span><span style="color: #000000">+</span><span style="color: #000000">1</span><span style="color: #000000">);<br />&nbsp;&nbsp;&nbsp;&nbsp;QueueItem</span><span style="color: #000000">&lt;</span><span style="color: #0000ff">const</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">char</span><span style="color: #000000">*&gt;</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">*</span><span style="color: #000000">pt&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;QueueItem</span><span style="color: #000000">&lt;</span><span style="color: #0000ff">const</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">char</span><span style="color: #000000">*&gt;</span><span style="color: #000000">(new_item);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">(empty())<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;head&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;tail&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;pt;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">队列中没有元素</span><span style="color: #008000"><br /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;eles{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tail</span><span style="color: #000000">-&gt;</span><span style="color: #000000">next&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;pt;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">添加新元素到列尾</span><span style="color: #008000"><br /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tail&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;pt;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />}<br />template</span><span style="color: #000000">&lt;&gt;</span><span style="color: #000000"><br /></span><span style="color: #0000ff">void</span><span style="color: #000000">&nbsp;Queue</span><span style="color: #000000">&lt;</span><span style="color: #0000ff">const</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">char</span><span style="color: #000000">*&gt;</span><span style="color: #000000">::pop()<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;QueueItem</span><span style="color: #000000">&lt;</span><span style="color: #0000ff">const</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">char</span><span style="color: #000000">*&gt;</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">*</span><span style="color: #000000">p&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;head;<br />&nbsp;&nbsp;&nbsp;&nbsp;delete&nbsp;head</span><span style="color: #000000">-&gt;</span><span style="color: #000000">item;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">删除队首元素</span><span style="color: #008000"><br /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;head&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;head</span><span style="color: #000000">-&gt;</span><span style="color: #000000">next;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">指向当前队首元素</span><span style="color: #008000"><br /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;delete&nbsp;p;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">删除零时指针</span><span style="color: #008000"><br /></span><span style="color: #000000">}<br /><br /></span><span style="color: #000000">4</span><span style="color: #000000">.类模板的部分特化<br />&nbsp;&nbsp;&nbsp;&nbsp;如果类模板有一个以上的模板形参，我们很有可能只要特化某些模板形参<br />&nbsp;&nbsp;&nbsp;&nbsp;而不是全部形参。这时我们就需要使用类的部分特化。<br /></span><span style="color: #008000">//</span><span style="color: #008000">定义模板类</span><span style="color: #008000"><br /></span><span style="color: #000000">template&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #0000ff">class</span><span style="color: #000000">&nbsp;T1,&nbsp;</span><span style="color: #0000ff">class</span><span style="color: #000000">&nbsp;T2</span><span style="color: #000000">&gt;</span><span style="color: #000000"><br /></span><span style="color: #0000ff">class</span><span style="color: #000000">&nbsp;some_template{<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;<img src="http://www.cppblog.com/Images/dot.gif"  alt="" /></span><span style="color: #008000"><br /></span><span style="color: #000000">};<br /><br /></span><span style="color: #008000">//</span><span style="color: #008000">定义模板类的部分特化：T2类型固定，部分特化T1类型</span><span style="color: #008000"><br /></span><span style="color: #000000">template</span><span style="color: #000000">&lt;</span><span style="color: #0000ff">class</span><span style="color: #000000">&nbsp;T1</span><span style="color: #000000">&gt;</span><span style="color: #000000"><br /></span><span style="color: #0000ff">class</span><span style="color: #000000">&nbsp;some_template</span><span style="color: #000000">&lt;</span><span style="color: #000000">T1,&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&gt;</span><span style="color: #000000">{<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;<img src="http://www.cppblog.com/Images/dot.gif"  alt="" /></span><span style="color: #008000"><br /></span><span style="color: #000000">};<br /></span><span style="color: #008000">//</span><span style="color: #008000">使用类模板的部分特化</span><span style="color: #008000"><br /></span><span style="color: #000000">some_template</span><span style="color: #000000">&lt;</span><span style="color: #0000ff">int</span><span style="color: #000000">,&nbsp;</span><span style="color: #0000ff">string</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;foo;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">使用模板类</span><span style="color: #008000"><br /></span><span style="color: #000000">some_template</span><span style="color: #000000">&lt;</span><span style="color: #0000ff">string</span><span style="color: #000000">,</span><span style="color: #0000ff">int</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;bar;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">使用模板类的部分特化</span><span style="color: #008000"><br /></span><span style="color: #000000">通过使用模板特化能解决一些在通常或者通用情况下无法解决的特殊问题。在掌握了基本的语法规范和实现方法后便可以加以应用。</span></div> <img src ="http://www.cppblog.com/aaxron/aggbug/201314.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/aaxron/" target="_blank">天下</a> 2013-06-26 11:36 <a href="http://www.cppblog.com/aaxron/archive/2013/06/26/201314.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>模板特化</title><link>http://www.cppblog.com/aaxron/archive/2012/02/07/165101.html</link><dc:creator>天下</dc:creator><author>天下</author><pubDate>Tue, 07 Feb 2012 06:45:00 GMT</pubDate><guid>http://www.cppblog.com/aaxron/archive/2012/02/07/165101.html</guid><wfw:comment>http://www.cppblog.com/aaxron/comments/165101.html</wfw:comment><comments>http://www.cppblog.com/aaxron/archive/2012/02/07/165101.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/aaxron/comments/commentRss/165101.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/aaxron/services/trackbacks/165101.html</trackback:ping><description><![CDATA[<div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #000000; ">#include&nbsp;</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">cstdio</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; "><br />#include&nbsp;</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">cstring</span><span style="color: #000000; ">&gt;</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;T</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; "><br />T&nbsp;mymax(</span><span style="color: #0000FF; ">const</span><span style="color: #000000; ">&nbsp;T&nbsp;t1,&nbsp;</span><span style="color: #0000FF; ">const</span><span style="color: #000000; ">&nbsp;T&nbsp;t2)<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">return</span><span style="color: #000000; ">&nbsp;t1&nbsp;</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">&nbsp;t2&nbsp;</span><span style="color: #000000; ">?</span><span style="color: #000000; ">&nbsp;t2&nbsp;:&nbsp;t1;<br />}<br /><br /></span><span style="color: #008000; ">//</span><span style="color: #008000; ">模板特化<br /></span><span style="color: #008000; ">//</span><span style="color: #008000; ">特化为绝对类型<br /></span><span style="color: #008000; ">//</span><span style="color: #008000; ">上述定义中template&nbsp;&lt;&nbsp;&gt;告诉编译器这是一个特化的模板。并且在声明特化模板之前一定要有非特化的声明！并且两个类的名字是一样的！<br /></span><span style="color: #008000; ">//</span><span style="color: #008000; ">特化的模板必须放在非特化的模板的之后<br /></span><span style="color: #008000; ">//</span><span style="color: #008000; ">否则编译器死给你看,如下:<br /></span><span style="color: #008000; ">//</span><span style="color: #008000; ">'const&nbsp;char&nbsp;*mymax(const&nbsp;char&nbsp;*,const&nbsp;char&nbsp;*)'&nbsp;is&nbsp;not&nbsp;a&nbsp;specialization&nbsp;of&nbsp;a&nbsp;function&nbsp;template</span><span style="color: #008000; "><br /></span><span style="color: #000000; "><br />template</span><span style="color: #000000; ">&lt;&gt;</span><span style="color: #000000; "><br /></span><span style="color: #0000FF; ">const</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">char</span><span style="color: #000000; ">*</span><span style="color: #000000; ">&nbsp;mymax(</span><span style="color: #0000FF; ">const</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">char</span><span style="color: #000000; ">*</span><span style="color: #000000; ">&nbsp;t1,</span><span style="color: #0000FF; ">const</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">char</span><span style="color: #000000; ">*</span><span style="color: #000000; ">&nbsp;t2)<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">return</span><span style="color: #000000; ">&nbsp;(strcmp(t1,t2)&nbsp;</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">0</span><span style="color: #000000; ">)&nbsp;</span><span style="color: #000000; ">?</span><span style="color: #000000; ">&nbsp;t2&nbsp;:&nbsp;t1;<br />}<br /><br /></span><span style="color: #008000; ">/*</span><span style="color: #008000; "><br />非模板函数<br />非模板函数具有最高的优先权<br />const&nbsp;char*&nbsp;mymax(const&nbsp;char*&nbsp;t1,const&nbsp;char*&nbsp;t2)<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;(strcmp(t1,t2)&nbsp;&lt;&nbsp;0)&nbsp;?&nbsp;t2&nbsp;:&nbsp;t1;<br />}<br /></span><span style="color: #008000; ">*/</span><span style="color: #000000; "><br /><br /></span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;main()<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;highest&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;mymax(</span><span style="color: #000000; ">5</span><span style="color: #000000; ">,</span><span style="color: #000000; ">10</span><span style="color: #000000; ">);<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">char</span><span style="color: #000000; ">&nbsp;c&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;mymax(</span><span style="color: #000000; ">'</span><span style="color: #000000; ">a</span><span style="color: #000000; ">'</span><span style="color: #000000; ">,&nbsp;</span><span style="color: #000000; ">'</span><span style="color: #000000; ">z</span><span style="color: #000000; ">'</span><span style="color: #000000; ">);<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">const</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">char</span><span style="color: #000000; ">*</span><span style="color: #000000; ">&nbsp;p1&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">"</span><span style="color: #000000; ">hello</span><span style="color: #000000; ">"</span><span style="color: #000000; ">;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">const</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">char</span><span style="color: #000000; ">*</span><span style="color: #000000; ">&nbsp;p2&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">"</span><span style="color: #000000; ">world</span><span style="color: #000000; ">"</span><span style="color: #000000; ">;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">const</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">char</span><span style="color: #000000; ">*</span><span style="color: #000000; ">&nbsp;p&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;mymax(p1,p2);&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">return</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">0</span><span style="color: #000000; ">;<br />}<br /><br /></span></div> <img src ="http://www.cppblog.com/aaxron/aggbug/165101.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/aaxron/" target="_blank">天下</a> 2012-02-07 14:45 <a href="http://www.cppblog.com/aaxron/archive/2012/02/07/165101.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>