﻿<?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++博客-陈陈</title><link>http://www.cppblog.com/chenchen/</link><description>C++</description><language>zh-cn</language><lastBuildDate>Thu, 23 Apr 2026 02:27:11 GMT</lastBuildDate><pubDate>Thu, 23 Apr 2026 02:27:11 GMT</pubDate><ttl>60</ttl><item><title>个人翻译Beyond the C++ Standard Library -2</title><link>http://www.cppblog.com/chenchen/archive/2005/12/31/2323.html</link><dc:creator>chenchen</dc:creator><author>chenchen</author><pubDate>Sat, 31 Dec 2005 09:23:00 GMT</pubDate><guid>http://www.cppblog.com/chenchen/archive/2005/12/31/2323.html</guid><wfw:comment>http://www.cppblog.com/chenchen/comments/2323.html</wfw:comment><comments>http://www.cppblog.com/chenchen/archive/2005/12/31/2323.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.cppblog.com/chenchen/comments/commentRss/2323.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/chenchen/services/trackbacks/2323.html</trackback:ping><description><![CDATA[<P>shared_ptr<BR>Header: "boost/shared_ptr.hpp"</P>
<P>几乎全部有效程序都需要一些引用记数(reference-counted)形式的智能指针.这些只能指针使我们不再需要自己写复杂的逻辑来控制被共享对象的生命期.当引用记数降到0,没有对象对这个被共享对象感兴趣,所以它自动delete.引用记数智能指针被分类为侵入式和非侵入式.类格式提供一个确定的功能函数或者数据成员来管理引用记数.那意味着设计类带有预见性的可以与侵入式,引用记数智能指针类,或者改进型共同工作.非侵入式,引用记数智能指针不需要管理任何类型.引用记数智能指针假设内存的所有权与存储他们的指针相关联.在没有智能指针帮助下使用共享对象的问题是必须有人最终delete共享内存.谁做,何时做?没有引用记数智能指针,一个外部的生命期管理必须强加于被管理的内存,它典型的表达了所有权集合之间存在很强的互相依附关系.那样妨碍了可重用性和增加了复杂度.</P>
<P>被管理的类或许有一个属性使它能成为一个优秀的候选来和引用记数智能指针一起使用.比如,事实上,它复制开销很大,或者它表示需要被多个实例共享,合理的共享所有权.还有的情况不存在一个明确的共享资源拥有者.应用引用记数智能指针使需要在对象间分享一个共享资源成为可能.同样在标准库中使没有危险和没有泄露的条件下存储对象指针成为可能,尤其面对异常时或者当从容器中移除元素时.当你在容器中存储指针时,你能得到多态的优势,效率改良(如果复制需要很大花费的话),还具备存储多个相同对象的能力,关联容器的专门检查.</P>
<P>在你有理由并决定使用引用记数智能指针后,怎样选择使用侵入式还是非侵入式的设计?非侵入式<BR>几乎总是较好的选择因为它的一般适用性,对现存代码影响少,灵活.你可以使用非侵入式,引用记数智能指针对那些你希望保持不变的类.通常的方法是改编一个类来和侵入式的一起工作,引用记数智能指针是从引用记数基类派生出来的.乍一看它的变化或许伴随着更多的开销.但是至少,它增加了相互依存关系和加强了可重用性.它同样增加了对象大小,或在一些范围内限制了可用性.</P>
<P><BR>一个shared_ptr可以由原生指针,另一个shared_ptr,一个std::auto_ptr,或者一个boost::weak_ptr创建.它同样可以传递第二个实参到shared_ptr的constructor,当做释放者.<BR>它会被最后调用来释放被共享资源.这是非常有用的对于管理那些不是通过new分配和delete销毁的资源(我们稍后将看到一些创建用户释放者的例子).shared_ptr被创建后,它会被像普通指针一样的使用,没有被明确删除的情况下回显示异常.</P>
<P>这是shared_ptr的一个部分纲要;最重要的成员和自由函数被列出来,随后将简短的讨论.</P>
<P>namespace boost {</P>
<P>&nbsp; template&lt;typename T&gt; class shared_ptr {<BR>&nbsp; public:<BR>&nbsp;&nbsp;&nbsp; template &lt;class Y&gt; explicit shared_ptr(Y* p);<BR>&nbsp;&nbsp;&nbsp; template &lt;class Y,class D&gt; shared_ptr(Y* p,D d);</P>
<P>&nbsp;&nbsp;&nbsp; ~shared_ptr();</P>
<P>&nbsp;&nbsp;&nbsp; shared_ptr(const shared_ptr &amp; r);<BR>&nbsp;&nbsp;&nbsp; template &lt;class Y&gt; explicit <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; shared_ptr(const weak_ptr&lt;Y&gt;&amp; r);<BR>&nbsp;&nbsp;&nbsp; template &lt;class Y&gt; explicit shared_ptr(std::auto_ptr&lt;Y&gt;&amp; r);</P>
<P>&nbsp;&nbsp;&nbsp; shared_ptr&amp; operator=(const shared_ptr&amp; r);</P>
<P>&nbsp;&nbsp;&nbsp; void reset(); <BR>&nbsp; <BR>&nbsp;&nbsp;&nbsp; T&amp; operator*() const;<BR>&nbsp;&nbsp;&nbsp; T* operator-&gt;() const;<BR>&nbsp;&nbsp;&nbsp; T* get() const;</P>
<P>&nbsp;&nbsp;&nbsp; bool unique() const;<BR>&nbsp;&nbsp;&nbsp; long use_count() const;</P>
<P>&nbsp;&nbsp;&nbsp; operator unspecified-bool-type() const;</P>
<P>&nbsp;&nbsp;&nbsp; void swap(shared_ptr&lt;T&gt;&amp; b);<BR>&nbsp; };</P>
<P>&nbsp; template &lt;class T,class U&gt;<BR>&nbsp;&nbsp;&nbsp; shared_ptr&lt;T&gt; static_pointer_cast(const shared_ptr&lt;U&gt;&amp; r);<BR>}</P>
<P>Members</P>
<P>template &lt;class Y&gt; explicit shared_ptr(Y* p);</P>
<P>这个constructor接管参数指针p的所有权.失参p必须是一个有效的Y的指针.创建后引用记数被设为1.仅当constructor为std::bad_alloc时抛出异常(它仅在引用记数没分配真种不太可能的情况下发生).</P>
<P>template &lt;class Y,class D&gt; shared_ptr(Y* p,D d);</P>
<P>此constructor有俩个参数.第一个是shared_ptr接管所有权的资源,第二个是负责释放资源的对象当shared_ptr被销毁.被存储的资源被传递给对象以d(p).p的有效值取决于d.如果reference counter不能被分配,shared_ptr抛出std::bad_alloc类型的异常.</P>
<P>shared_ptr(const shared_ptr&amp; r);</P>
<P>在r中被存储资源通过创建shared_ptr对象被分享,reference count加1.这个copy constructor不抛出异常.</P>
<P>template &lt;class Y&gt; explicit shared_ptr(const weak_ptr&lt;Y&gt;&amp; r);</P>
<P>从weak_ptr(在本章后面介绍)创建一个shared_ptr.它使weak_ptr具有thread-safe的用处,因为被共享资源的reference count将通过weak_ptr的参数自增(weak_ptr不会影响被共享资源的reference count).如果weak_ptr是空的话(r.use_count()==0),shared_ptr抛出bad_weak_ptr类型的异常.</P>
<P>template &lt;typename Y&gt; shared_ptr(std::auto_ptr&lt;Y&gt;&amp; r);</P>
<P>这个construction从auto_ptr接过r存储对象的所有权通过存储一个指针副本并释放原auto_ptr.创建后reference count是1.代表r,当然,耗尽内存的情况下,reference counter无法分配将抛出std::bad_alloc</P>
<P>~shared_ptr();</P>
<P>shared_ptr的destructor减少reference count 1.如果count为0,被指资源delete.delete指针将通过调用operator delete或者使用用户提供的释放者对象来销毁,此对象将被存储的指针作为它的唯一参数调用.destructor不抛出异常.</P>
<P>shared_ptr&amp; operator=(const shared_ptr&amp; r);&nbsp; </P>
<P>copy assignment operator共享r中的资源并停止共享当前被共享的资源.此copy assignment operator不抛出异常</P>
<P>void reset();</P>
<P>此函数被用于停止共享被存储指针的所有权.被共享资源的reference count变0.</P>
<P>T&amp; operator*() const;</P>
<P>此operator返回一个被存储指针所指向对象的引用,如果指针为null,operator*导致未定义行为.此operator不抛出异常</P>
<P>T* operator-&gt;() const;</P>
<P>此operator返回被存储的指针.同operator*一起使smart pointer看起来想普通指针.此operator不抛出异常</P>
<P>T* get() const;</P>
<P>get function是检查被存储指针是否为null的首选方法(在null情形下operator* and operator-&gt;导致为定义行为).注意它同样可以测试一个shared_ptr是否包含一个有效指针通过使用暗式Boolean类型转换.此function不抛出异常.</P>
<P>bool unique() const;</P>
<P>此函数返回true当shared_ptr是被存储指针的唯一拥有者;否则,返回false.unique不抛出异常.</P>
<P>long use_count() const;</P>
<P>此函数返回指针的reference count.在调试用途中尤其有用,因为他能被用来获得reference count的简短信息在执行程序的关键点处.保守的使用它.为了使一些shared_ptr的接口可以执行,计算reference count也许有很大开销甚至是不可能的.此函数不抛出异常.</P>
<P>operator unspecified-bool-type() const;</P>
<P>它暗式转换为一个类型,unspecified-bool-type,使用Boolean来测试一个smart pointer成为可能.如果当前存储一个有效指针则为true,否则,则为false.此转换函数返回的类型是为规定的.使用bool作为返回类型将允许一些无意义的操作,代表性的,使用safe bool idiom来实现,的确是一个漂亮的办法来确保仅当适当的逻辑测试才能被使用.此函数不抛出异常.</P>
<P>void swap(shared_ptr&lt;T&gt;&amp; b);</P>
<P>它有时方便的交换俩个shared_ptrs的内容.swap函数交换被存储的指针(和它们的reference counts).此函数不抛出异常.</P>
<P>Free Functions</P>
<P>template &lt;typename T,typename U&gt;<BR>&nbsp;shared_ptr&lt;T&gt; static_pointer_cast(const shared_ptr&lt;U&gt;&amp; r); </P>
<P>执行一个static_cast从被存储的指针到shared_ptr,我们可以检查指针然后转换它,但是我们不能存储它在另外一个shared_ptr中;新的shared_ptr将认为它是指针关联的资源的第一个管理者.它可以被补救通过static_pointer_cast.使用这个函数确保指针剩余的reference count不变性.static_pointer_cast不抛出异常.</P>
<P>Usage</P>
<P>shared_ptr解决的主要问题是在正确是时间delete被多个用户共享的资源.这里有个直观的例子,<BR>有俩个classes, A和B,共享一个int实例.使用boost::shared_ptr,你需要包含"boost/shared_ptr.hpp".</P>
<P>#include "boost/shared_ptr.hpp"<BR>#include &lt;cassert&gt;</P>
<P>class A {<BR>&nbsp; boost::shared_ptr&lt;int&gt; no_;<BR>public:<BR>&nbsp; A(boost::shared_ptr&lt;int&gt; no) : no_(no) {}<BR>&nbsp; void value(int i) {<BR>&nbsp;&nbsp;&nbsp; *no_=i;<BR>&nbsp; }<BR>};</P>
<P>class B {<BR>&nbsp; boost::shared_ptr&lt;int&gt; no_;<BR>public:<BR>&nbsp; B(boost::shared_ptr&lt;int&gt; no) : no_(no) {}<BR>&nbsp; int value() const {<BR>&nbsp;&nbsp;&nbsp; return *no_;<BR>&nbsp; }<BR>};</P>
<P>int main() {<BR>&nbsp;&nbsp;&nbsp; boost::shared_ptr&lt;int&gt; temp(new int(14));<BR>&nbsp;&nbsp;&nbsp; A a(temp);<BR>&nbsp;&nbsp;&nbsp; B b(temp);<BR>&nbsp;&nbsp;&nbsp; a.value(28);<BR>&nbsp;&nbsp;&nbsp; assert(b.value()==28);<BR>}</P>
<P>classes A和B都存储一个shared_ptr&lt;int&gt;.当创造A和B的实例时,shared_ptr temp被传递进了他们的constructor.这以为着这三个shared_ptr,a,b,和temp现在引用一个共同的int实例.我们用指针达到了分享一个int的目的,A和B将计算出它应该在何时被delete.在本例中,reference count是3直到main的结束,所有的shared_ptr跳出作用域,减少count知道为0,允许最后一个smart pointers来delete共享的int.</P>
<P>&nbsp;</P><img src ="http://www.cppblog.com/chenchen/aggbug/2323.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/chenchen/" target="_blank">chenchen</a> 2005-12-31 17:23 <a href="http://www.cppblog.com/chenchen/archive/2005/12/31/2323.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>个人翻译Beyond the C++ Standard Library</title><link>http://www.cppblog.com/chenchen/archive/2005/12/30/2299.html</link><dc:creator>chenchen</dc:creator><author>chenchen</author><pubDate>Fri, 30 Dec 2005 12:43:00 GMT</pubDate><guid>http://www.cppblog.com/chenchen/archive/2005/12/30/2299.html</guid><wfw:comment>http://www.cppblog.com/chenchen/comments/2299.html</wfw:comment><comments>http://www.cppblog.com/chenchen/archive/2005/12/30/2299.html#Feedback</comments><slash:comments>6</slash:comments><wfw:commentRss>http://www.cppblog.com/chenchen/comments/commentRss/2299.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/chenchen/services/trackbacks/2299.html</trackback:ping><description><![CDATA[<H3 class=docSection1Title><FONT size=5>scoped_array</FONT></H3><A name=ch01index54></A><A name=ch01lev2sec10></A>
<H4 class=docSection2Title><FONT size=4>Header : <TT>"boost/scoped_array.hpp"</TT></FONT></H4>
<H4 class=docSection2Title><TT>对于使用动态分配的数祖来说vector经常是我们最好的选择.但是有俩个情况使用普通数组更为妥善.</TT></H4>
<H4 class=docSection2Title><TT>1:优化,vector带来过大的开销在体积和速度上.</TT></H4>
<H4 class=docSection2Title><TT>2:表达的意图,使用长度固定的数组</TT></H4>
<H4 class=docSection2Title><TT>动态数组暴露出和普通指针一样的危险,伴随着调用delete操作符来代替delete[]操作符的错误,</TT></H4>
<H4 class=docSection2Title><TT>我在很多地方看到过这个错误,只一个就不敢想象,何况应用的如此广泛在容器类的所有权中!</TT></H4>
<H4 class=docSection2Title><TT>scoped_array用于数组类似scoped_ptr作用于单个对象的指针,它delete内存,不同之处是scoped_array</TT></H4>
<H4 class=docSection2Title><TT>使用操作符delete[].</TT></H4>
<H4 class=docSection2Title><TT>scoped_array是一个单独类而不是scoped_ptr的特化是因为使用metaprogramming技术来分别单个对象</TT></H4>
<H4 class=docSection2Title><TT>的指针和数组指针是不可能的.</TT></H4>
<H4 class=docSection2Title><TT>不管如何努力的去区别,没有人发现一个可靠的方法来实现,因为数组类型太容易退化到指针类型并不带有</TT></H4>
<H4 class=docSection2Title><TT>任何类型转化信息来说明它到底指像的是什么类型.结果你有责任采用scoped_array而不是<TT>scoped_ptr,</TT></TT></H4>
<H4 class=docSection2Title><TT><TT>就像你必须使用delete[] operator而不是delete operator.优势是scoped_array帮你处理delete,</TT></TT></H4>
<H4 class=docSection2Title><TT><TT>并且提醒你它处理的是数组,原生指针却做不到此点.</TT></TT><TT><TT></H4>
<H4 class=docSection2Title>
<P class=docText><FONT size=2>scoped_array和scoped_ptr和相似,不同的是它提供operator[]来模仿原生数组.</FONT></P>
<P class=docText><FONT size=2>scoped_array优于原始,动态分配数组之一.它管理动态数组的生命期,与scoped_ptr如何</FONT><FONT size=2>管理所指向对象</FONT></P>
<P class=docText><FONT size=2>的生命期类似,虽然如此,但很多情况下,std::vector却更可取,因为它更</FONT><FONT size=2>灵活,更强大.</FONT></P>
<P class=docText><FONT size=2>当你需要固定长度的数组,使用scoped_array而不是</FONT><FONT size=3><TT>std::vector</TT>.</FONT></P></TT></TT></H4><img src ="http://www.cppblog.com/chenchen/aggbug/2299.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/chenchen/" target="_blank">chenchen</a> 2005-12-30 20:43 <a href="http://www.cppblog.com/chenchen/archive/2005/12/30/2299.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>伪随机数产生器</title><link>http://www.cppblog.com/chenchen/archive/2005/12/28/2210.html</link><dc:creator>chenchen</dc:creator><author>chenchen</author><pubDate>Wed, 28 Dec 2005 05:35:00 GMT</pubDate><guid>http://www.cppblog.com/chenchen/archive/2005/12/28/2210.html</guid><wfw:comment>http://www.cppblog.com/chenchen/comments/2210.html</wfw:comment><comments>http://www.cppblog.com/chenchen/archive/2005/12/28/2210.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/chenchen/comments/commentRss/2210.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/chenchen/services/trackbacks/2210.html</trackback:ping><description><![CDATA[class subtractive_rng : public unary_function&lt;unsigned int, unsigned int&gt; {<BR>private:<BR>&nbsp; unsigned int _M_table[55];<BR>&nbsp; size_t _M_index1;<BR>&nbsp; size_t _M_index2;<BR>public:<BR>&nbsp; unsigned int operator()(unsigned int __limit) {<BR>&nbsp;&nbsp;&nbsp; _M_index1 = (_M_index1 + 1) % 55;<BR>&nbsp;&nbsp;&nbsp; _M_index2 = (_M_index2 + 1) % 55;<BR>&nbsp;&nbsp;&nbsp; _M_table[_M_index1] = _M_table[_M_index1] - _M_table[_M_index2];<BR>&nbsp;&nbsp;&nbsp; return _M_table[_M_index1] % __limit;<BR>&nbsp; }<BR><BR>&nbsp; void _M_initialize(unsigned int __seed)<BR>&nbsp; {<BR>&nbsp;&nbsp;&nbsp; unsigned int __k = 1;<BR>&nbsp;&nbsp;&nbsp; _M_table[54] = __seed;<BR>&nbsp;&nbsp;&nbsp; size_t __i;<BR>&nbsp;&nbsp;&nbsp; for (__i = 0; __i &lt; 54; __i++) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; size_t __ii = (21 * (__i + 1) % 55) - 1;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _M_table[__ii] = __k;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; __k = __seed - __k;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; __seed = _M_table[__ii];<BR>&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp; for (int __loop = 0; __loop &lt; 4; __loop++) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (__i = 0; __i &lt; 55; __i++)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _M_table[__i] = _M_table[__i] - _M_table[(1 + __i + 30) % 55];<BR>&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp; _M_index1 = 0;<BR>&nbsp;&nbsp;&nbsp; _M_index2 = 31;<BR>&nbsp; }<BR><BR>&nbsp; subtractive_rng(unsigned int __seed) { _M_initialize(__seed); }<BR>&nbsp; subtractive_rng() { _M_initialize(161803398u); }<BR>};<img src ="http://www.cppblog.com/chenchen/aggbug/2210.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/chenchen/" target="_blank">chenchen</a> 2005-12-28 13:35 <a href="http://www.cppblog.com/chenchen/archive/2005/12/28/2210.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>stl 函数对象</title><link>http://www.cppblog.com/chenchen/archive/2005/12/27/2190.html</link><dc:creator>chenchen</dc:creator><author>chenchen</author><pubDate>Tue, 27 Dec 2005 13:14:00 GMT</pubDate><guid>http://www.cppblog.com/chenchen/archive/2005/12/27/2190.html</guid><wfw:comment>http://www.cppblog.com/chenchen/comments/2190.html</wfw:comment><comments>http://www.cppblog.com/chenchen/archive/2005/12/27/2190.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/chenchen/comments/commentRss/2190.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/chenchen/services/trackbacks/2190.html</trackback:ping><description><![CDATA[<P><BR>template &lt;class _Tp&gt;<BR>struct _Identity : public unary_function&lt;_Tp,_Tp&gt; {<BR>&nbsp; const _Tp&amp; operator()(const _Tp&amp; __x) const { return __x; }<BR>};</P>
<P>template &lt;class _Tp&gt; struct identity : public _Identity&lt;_Tp&gt; {};<BR></P>
<P>//验证模板参数是不是一个函数对象类型<BR><BR>template &lt;class _Pair&gt;<BR>struct _Select1st : public unary_function&lt;_Pair, typename _Pair::first_type&gt; {<BR>&nbsp; const typename _Pair::first_type&amp; operator()(const _Pair&amp; __x) const {<BR>&nbsp;&nbsp;&nbsp; return __x.first;<BR>&nbsp; }<BR>};</P>
<P>template &lt;class _Pair&gt;<BR>struct _Select2nd : public unary_function&lt;_Pair, typename _Pair::second_type&gt;<BR>{<BR>&nbsp; const typename _Pair::second_type&amp; operator()(const _Pair&amp; __x) const {<BR>&nbsp;&nbsp;&nbsp; return __x.second;<BR>&nbsp; }<BR>};</P>
<P>template &lt;class _Pair&gt; struct select1st : public _Select1st&lt;_Pair&gt; {};<BR>template &lt;class _Pair&gt; struct select2nd : public _Select2nd&lt;_Pair&gt; {};<BR></P>
<P>//忽略模板参数为pair类型所包含的相应参数(第一个参数和第二个参数)<BR><BR>template &lt;class _Arg1, class _Arg2&gt;<BR>struct _Project1st : public binary_function&lt;_Arg1, _Arg2, _Arg1&gt; {<BR>&nbsp; _Arg1 operator()(const _Arg1&amp; __x, const _Arg2&amp;) const { return __x; }<BR>};</P>
<P>template &lt;class _Arg1, class _Arg2&gt;<BR>struct _Project2nd : public binary_function&lt;_Arg1, _Arg2, _Arg2&gt; {<BR>&nbsp; _Arg2 operator()(const _Arg1&amp;, const _Arg2&amp; __y) const { return __y; }<BR>};</P>
<P>template &lt;class _Arg1, class _Arg2&gt; <BR>struct project1st : public _Project1st&lt;_Arg1, _Arg2&gt; {};</P>
<P>template &lt;class _Arg1, class _Arg2&gt;<BR>struct project2nd : public _Project2nd&lt;_Arg1, _Arg2&gt; {};<BR></P>
<P>//忽略调用运算符时相应的参数</P>
<P>template &lt;class _Result&gt;<BR>struct _Constant_void_fun {<BR>&nbsp; typedef _Result result_type;<BR>&nbsp; result_type _M_val;</P>
<P>&nbsp; _Constant_void_fun(const result_type&amp; __v) : _M_val(__v) {}<BR>&nbsp; const result_type&amp; operator() const { return _M_val; }<BR>};&nbsp; </P>
<P>template &lt;class _Result, class _Argument&gt;<BR>struct _Constant_unary_fun {<BR>&nbsp; typedef _Argument argument_type;<BR>&nbsp; typedef&nbsp; _Result&nbsp; result_type;<BR>&nbsp; result_type _M_val;</P>
<P>&nbsp; _Constant_unary_fun(const result_type&amp; __v) : _M_val(__v) {}<BR>&nbsp; const result_type&amp; operator()(const _Argument&amp;) const { return _M_val; }<BR>};</P>
<P>template &lt;class _Result, class _Arg1, class _Arg2&gt;<BR>struct _Constant_binary_fun {<BR>&nbsp; typedef&nbsp; _Arg1&nbsp;&nbsp; first_argument_type;<BR>&nbsp; typedef&nbsp; _Arg2&nbsp;&nbsp; second_argument_type;<BR>&nbsp; typedef&nbsp; _Result result_type;<BR>&nbsp; _Result _M_val;</P>
<P>&nbsp; _Constant_binary_fun(const _Result&amp; __v) : _M_val(__v) {}<BR>&nbsp; const result_type&amp; operator()(const _Arg1&amp;, const _Arg2&amp;) const {<BR>&nbsp;&nbsp;&nbsp; return _M_val;<BR>&nbsp; }<BR>};<BR></P>
<P>//返回一个普通变量的const副本,无论参数为何,只返回同一个值的函数对象<BR><BR>template &lt;class _Result&gt;<BR>struct constant_void_fun : public _Constant_void_fun&lt;_Result&gt; {<BR>&nbsp; constant_void_fun(const _Result&amp; __v) : _Constant_void_fun&lt;_Result&gt;(__v) {}<BR>};&nbsp; </P>
<P>template &lt;class _Result,<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; class _Argument __STL_DEPENDENT_DEFAULT_TMPL(_Result)&gt;<BR>struct constant_unary_fun : public _Constant_unary_fun&lt;_Result, _Argument&gt;<BR>{<BR>&nbsp; constant_unary_fun(const _Result&amp; __v)<BR>&nbsp;&nbsp;&nbsp; : _Constant_unary_fun&lt;_Result, _Argument&gt;(__v) {}<BR>};</P>
<P><BR>template &lt;class _Result,<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; class _Arg1 __STL_DEPENDENT_DEFAULT_TMPL(_Result),<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; class _Arg2 __STL_DEPENDENT_DEFAULT_TMPL(_Arg1)&gt;<BR>struct constant_binary_fun<BR>&nbsp; : public _Constant_binary_fun&lt;_Result, _Arg1, _Arg2&gt;<BR>{<BR>&nbsp; constant_binary_fun(const _Result&amp; __v)<BR>&nbsp;&nbsp;&nbsp; : _Constant_binary_fun&lt;_Result, _Arg1, _Arg2&gt;(__v) {}<BR>};<BR></P>
<P>//__STL_DEPENDENT_DEFAULT_TMPL 是一个宏，意思是如果编译器不支持默认模板参数，则使用上一级模板参数<BR><BR>template &lt;class _Result&gt;<BR>inline constant_void_fun&lt;_Result&gt; constant0(const _Result&amp; __val)<BR>{<BR>&nbsp; return constant_void_fun&lt;_Result&gt;(__val);<BR>}</P>
<P>template &lt;class _Result&gt;<BR>inline constant_unary_fun&lt;_Result,_Result&gt; constant1(const _Result&amp; __val)<BR>{<BR>&nbsp; return constant_unary_fun&lt;_Result,_Result&gt;(__val);<BR>}</P>
<P>template &lt;class _Result&gt;<BR>inline constant_binary_fun&lt;_Result,_Result,_Result&gt; <BR>constant2(const _Result&amp; __val)<BR>{<BR>&nbsp; return constant_binary_fun&lt;_Result,_Result,_Result&gt;(__val);<BR>}<BR><BR>//函数返回一个只返回常量和输入参数无关的函数对象</P><img src ="http://www.cppblog.com/chenchen/aggbug/2190.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/chenchen/" target="_blank">chenchen</a> 2005-12-27 21:14 <a href="http://www.cppblog.com/chenchen/archive/2005/12/27/2190.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>