﻿<?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>IT博客-黎明</title><link>http://www.cnitblog.com/dlpresident/</link><description>从这里起步－－通向软件颠峰</description><language>zh-cn</language><lastBuildDate>Tue, 05 May 2026 00:09:53 GMT</lastBuildDate><pubDate>Tue, 05 May 2026 00:09:53 GMT</pubDate><ttl>60</ttl><item><title>Visual C++使用中的问题讨论</title><link>http://www.cnitblog.com/dlpresident/archive/2007/10/29/35559.html</link><dc:creator>董礼</dc:creator><author>董礼</author><pubDate>Mon, 29 Oct 2007 15:19:00 GMT</pubDate><guid>http://www.cnitblog.com/dlpresident/archive/2007/10/29/35559.html</guid><description><![CDATA[<p>Boost如何让VC6以实现mem_fun可以接收返回值为void的成员函数</p>
<p>VC6自带的STL，mem_fun可以接收的成员函数返回值不能为void。<br>在&lt;functional&gt;文件中可以看到具体的实现代码为：</p>
<p>template&lt;class _Return, class _Type&gt;<br>class mem_fun_t<br>{<br>public:<br>//construction...</p>
<p>_Return operator()(_Type *_P) const<br>{return ((_P-&gt;*_FuncPtr)()); }<br>private:<br>//member function pointer ...<br>};</p>
<p>当_Return为void时，VC6会报一个编译错误：void' function returning a value。</p>
<p>有心想解决一下。首先，尝试使用static_cast。</p>
<p>_Return operator()(_Type *_P) const<br>{return static_cast&lt;void)((_P-&gt;*_FuncPtr)()); }</p>
<p>发现报同样错误，看来VC6确实对标准支持一般。</p>
<p><br>然后当然想采用特化，对返回值类型进行void特化，但是VC6根本不支持部分特化，例如：</p>
<p>template&lt;class _Type&gt;<br>class mem_fun_t&lt;void, _Type&gt;<br>{..<br>};<br>报编译错误，重复的模板定义。 template class has already been defined as a non-template class</p>
<p>幸亏VC仍然支持完全特化，于是采用&#8220;增加一层&#8220;定律，由于只有返回值为void的时侯需要特别处理，<br>因此定义一个通用模板，然后对void进行完全特化：</p>
<p>template &lt;class Return&gt; struct return_trait<br>{<br>...<br>};</p>
<p><br>template&lt;&gt; struct return_trait&lt;void&gt;<br>{<br>...<br>};</p>
<p>下面的代码就是根据boost实现来的，简化了很多。毕竟阅读困难。</p>
<p>在这两者之间就可以对返回类型为void的情况进行特别处理了：<br>通用模板定义如下：<br>template &lt;class Return&gt; struct return_trait<br>{<br>template&lt;class Return, class Type, class F&gt; <br>struct inner_mem_fun_type<br>{<br>F func_;<br>inner_mem_fun_type(F f) : func_(f) {}</p>
<p>Return operator()(Type * type)<br>{<br>return (type-&gt;*func_)();<br>}<br>｝<br>};</p>
<p>void的完全特化模板和上面一模一样，只是将<br>return (type-&gt;*func_)();<br>中的return去掉即可，就不多写了。其中boost使用了宏和#include来实现这个功能。</p>
<p>然后定义一个模板函数，用来自动实例化合适的模板类型；<br>template&lt;class Return, class Type&gt; <br>return_trait&lt;Return&gt;::inner_mem_fun_type&lt;Return, Type, Return (Type::*)()&gt; <br>mem_func(Return (Type::*f)())<br>{<br>return return_trait&lt;Return&gt;::inner_mem_fun_type&lt;Return, Type, Return (Type::*)()&gt;(f);<br>}</p>
<p>boost其实在mem_fn中又创建了一个间接层次，我发现上面直接返回内嵌类VC6也可以编译。可能是因为其他的编译器需要这样处理。其中inner_mem_fun_type接收3个参数，第3个参数为成员函数指针类型，完全可以由Return,Type确定，但是发现如果不加上这个，VC6出现internal compiler error。我在这上面就折腾了很久。也不知道boost是如何发现这个解决方法的。</p>
<p><br>举一反三，对于类似的部分特化的需求，在VC6下都应该可以使用该方法解决。<br>例如，一个模板类有2个类型参数T1, T2，其中需要对int, T2进行部分特化处理。</p>
<p>最标准的当然是<br>template&lt;class Type1, class Type2&gt; struct Foo<br>{<br>...<br>};</p>
<p>对int, Type2部分特化<br>template&lt;class Type2&gt; struct&lt;int, Type2&gt;Foo<br>{<br>...<br>};</p>
<p>前面说了VC6不支持这种部分特化，因此可以如下；<br>提出Type1，定义一个嵌套结构：<br>template&lt;class Type1&gt; struct type_traits<br>{<br>template&lt;class Type1, class Type2&gt; struct Foo<br>{<br>};<br>};</p>
<p>对Type1为int进行完全特化：<br>template&lt;&gt; struct type_traits&lt;int&gt;<br>{<br>template&lt;class Type1, class Type2&gt; struct Foo<br>{<br>};<br>};</p>
<p>使用之：</p>
<p>type_traits&lt;double&gt;::Foo&lt;double, double&gt; f1;<br>type_traits&lt;int&gt;::Foo&lt;int, double&gt; f2;</p>
<p>很好。但是毕竟毕竟繁琐，当然想搞个模板成员函数推演出来：</p>
<p>template&lt;class Type1, class Type2&gt;<br>type_traits&lt;Type1&gt;::Foo&lt;Type1, Type2&gt; make_foo(Type1 t1, Type2 t2)<br>{<br>return type_traits&lt;Type1&gt;::Foo&lt;Type1, Type2&gt;(t1, t2);<br>}</p>
<p>结果到这一步又是internal compiler error。</p>
<p>看来还又得学习boost中的，使用继承关系。再来：</p>
<p>定义一个Wapper class，从嵌套类type_traits::Foo派生</p>
<p>template&lt;class Type1, class Type2&gt; <br>struct FooWapper : public type_traits&lt;Type1&gt;::Foo&lt;Type1, Type2&gt;<br>{<br>FooWapper(Type1 t1, Type2 t2) : type_traits&lt;Type1&gt;::Foo&lt;Type1, Type2&gt;(t1, t2) {}<br>};</p>
<p>maker函数返回FooWapper模板类，而不是嵌套的模板类<br>template&lt;class Type1, class Type2&gt;<br>FooWapper&lt;Type1, Type2&gt; make_foo(Type1 t1, Type2 t2)<br>{<br>return FooWapper&lt;Type1, Type2&gt;(t1, t2);<br>}</p>
<p>再试：<br>make_foo(1, 2.0);<br>make_foo('a', 2.0);</p>
<p>编译成功。测试也对。通过这种手法，应该可以在VC6下解决一部分部分特化的问题，如果需要特化的类型以定的话。但是想对例如T*这种进行指针特化估计是没有希望了。不错。boost！</p>
<p>完整的源程序：</p>
<p>//通用Type1, Type2<br>template&lt;class Type1&gt; struct type_traits<br>{<br>template&lt;class Type1, class Type2&gt; struct Foo<br>{<br>Foo(Type1 t1, Type2 t2)<br>{<br>std::cout &lt;&lt; "noint+type1" &lt;&lt; std::endl;<br>}<br>};<br>};</p>
<p>//特化的int，Type2<br>template&lt;&gt; struct type_traits&lt;int&gt;<br>{<br>template&lt;class Type1, class Type2&gt; struct Foo<br>{<br>Foo(Type1 t1, Type2 t2)<br>{<br>std::cout &lt;&lt; "int+type2" &lt;&lt; std::endl;<br>}<br>};<br>};</p>
<p>//Wrapper 类<br>template&lt;class Type1, class Type2&gt; <br>struct FooWapper : public type_traits&lt;Type1&gt;::Foo&lt;Type1, Type2&gt;<br>{<br>FooWapper(Type1 t1, Type2 t2) : type_traits&lt;Type1&gt;::Foo&lt;Type1, Type2&gt;(t1, t2) {}<br>};</p>
<p><br>//maker函数用于推演<br>template&lt;class Type1, class Type2&gt;<br>FooWapper&lt;Type1, Type2&gt; inline make_foo(Type1 t1, Type2 t2)<br>{<br>return FooWapper&lt;Type1, Type2&gt;(t1, t2);<br>}</p>
<p>//测试程序<br>int main()<br>{<br>make_foo(1, 2.0); //调用特化的&lt;int, type2&gt;<br>make_foo('a', 2.0); //调用通用的&lt;type1, type2&gt;<br>}<br></p>
<img src ="http://www.cnitblog.com/dlpresident/aggbug/35559.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/dlpresident/" target="_blank">董礼</a> 2007-10-29 23:19 <a href="http://www.cnitblog.com/dlpresident/archive/2007/10/29/35559.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>男人的爱情</title><link>http://www.cnitblog.com/dlpresident/archive/2007/10/29/35558.html</link><dc:creator>董礼</dc:creator><author>董礼</author><pubDate>Mon, 29 Oct 2007 15:14:00 GMT</pubDate><guid>http://www.cnitblog.com/dlpresident/archive/2007/10/29/35558.html</guid><description><![CDATA[<table style="TABLE-LAYOUT: fixed">
    <tbody>
        <tr>
            <td>
            <div class=cnt><font color=#00cc00 size=2>1.男人是社会的主体,不管你信或不信.所以男人应该有种责任感.<br></font><font color=#00cc00 size=2>2.25岁之前,请记得,爱情通常是假的,或者不是你所想象的那样纯洁和永远.如果你过了25岁,那么你应该懂得这个道理.<br></font><font color=#00cc00 size=2>3.吃饭7成饱最舒服.对待女友最多也请你保持在7成.<br></font><font color=#00cc00 size=2>4.30岁之前请爱惜自己的身体,前30年你找病,后30年病找你.如果你过了30岁,你自然也会懂得这个道理.<br></font><font color=#00cc00 size=2>5.事业远比爱情重要.如果说事业都不能永恒,那么爱情只能算是昙花一现.<br></font><font color=#00cc00 size=2>6.不要轻易接受追求你的女孩.女追男隔层纱.如果你很容易就陷进去,你会发现你会错过很多东西,失去很多东西.<br></font><font color=#00cc00 size=2>7.请你相信,能用钱解决的问题,都不是问题.如果你认为钱索王道,有钱有女人,没钱没女人,那么.女人不是问题.<br></font><font color=#00cc00 size=2>8.请永远积极向上.每个男人都有他可爱的地方,但是不可爱的地方只有不积极面对生活.<br></font><font color=#00cc00 size=2>9.不要连续2次让同一个女人伤害.好马不吃回头草,是有他道理的.如果认真考虑过该分手,那么请不要做任何舍不得的行动.<br></font><font color=#00cc00 size=2>10.如果你和你前女友能做朋友,那么你要问自己:为什么?如果分手后还是朋友,那么只有2个可能:.你们当初都只是玩玩而已,没付出彼此最真的感情.或者:必定有个人是在默默的付出无怨无悔!<br></font><font color=#00cc00 size=2>11.永远不要太相信女人在恋爱时的甜言蜜语.都说女人爱听甜言蜜语,其实,男人更喜欢.<br></font><font color=#00cc00 size=2>12.请不要为自己的相貌或者身高过分担心和自卑.人是动物,但是区别于动物.先天条件并不是阻挡你好好生活的借口.人的心灵远胜于相貌,请相信这点.如果有人以相貌取人,那么你也没必要太在意.因为他从某种意义来讲,只是只动物.你会跟动物怄气吗?<br></font><font color=#00cc00 size=2>13.失恋时,只有2种可能,要么你爱她她不爱你,或者相反.那么,当你爱的人不再爱你,或者从来没爱过你时.你没有遗憾,因为你失去的只是一个不爱你的人<br></font><font color=#00cc00 size=2>14.请不要欺骗善良的女孩.这个世界上,善良的女孩太少.<br></font><font color=#00cc00 size=2>15.不能偏激的认为金钱万能,至少,金钱治不好艾滋病.<br></font><font color=#00cc00 size=2>16.请一定要有自信.你就是一道风景,没必要在别人风景里面仰视.<br></font><font color=#00cc00 size=2>17.受到再大的打击,只要生命还在,请相信每天的太阳都是新的.<br></font><font color=#00cc00 size=2>18.爱情永远不可能是天平.你想在爱情里幸福就要舍得伤心.<br></font><font size=2><font color=#00cc00>19.如果你喜欢一个认为别人应该对她好的mm,请尽早放弃.没有人是应该对一个人好的.如果她不明白这个道理,也就是她根本不懂得珍惜.<br></font><font color=#00cc00>20.不要因为寂寞而'找</font></font><a><font color=#00cc00 size=2>'gf</font></a><font color=#00cc00 size=2>,寂寞男人请要学会品味寂寞.请记住:即使寂寞,远方黑暗的夜空下,一定有人和你一样,寂寞的人不同,仰望的星空却是唯一.<br></font><font color=#00cc00 size=2>21.任何事没有永远.也别问怎样才能永远.生活有很多无奈.请尽量充实自己,充实生活.请善待生活.<br></font></div>
            </td>
        </tr>
    </tbody>
</table>
<img src ="http://www.cnitblog.com/dlpresident/aggbug/35558.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/dlpresident/" target="_blank">董礼</a> 2007-10-29 23:14 <a href="http://www.cnitblog.com/dlpresident/archive/2007/10/29/35558.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>