?!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> c++11中的move与forward-南软g开发|׃软g开?南赢dU技软g开发公?/title> <meta name="keywords" content="c++11中的move与forward"/> <meta name="description" content="一.move关于lvaue和rvalue,在c++11以前存在一个有的现象QT&指向lvalueQconstT&卛_以指向lvalue也可以指向rvalue?nbsp;但就是没有一U引用类型,可以限制为只指向rvalue. q乍h好像也不是很大问题,但事实上"/> <link href="/css/style.css" rel="stylesheet" type="text/css" /> <meta http-equiv="Cache-Control" content="no-transform" /> <meta http-equiv="Cache-Control" content="no-siteapp" /> </head> <body> <div style="position:fixed;left:-9000px;top:-9000px;"><dfn id="orz4q"><noscript id="orz4q"><xmp id="orz4q"><output id="orz4q"></output></xmp></noscript></dfn><strong id="orz4q"><dl id="orz4q"></dl></strong><ol id="orz4q"><p id="orz4q"><nav id="orz4q"><pre id="orz4q"></pre></nav></p></ol><dfn id="orz4q"></dfn><small id="orz4q"><optgroup id="orz4q"></optgroup></small><center id="orz4q"><small id="orz4q"><track id="orz4q"><rp id="orz4q"></rp></track></small></center><table id="orz4q"><ruby id="orz4q"><dl id="orz4q"><del id="orz4q"></del></dl></ruby></table><rt id="orz4q"></rt><output id="orz4q"></output><mark id="orz4q"></mark><dl id="orz4q"></dl><div id="orz4q"></div><optgroup id="orz4q"></optgroup><address id="orz4q"><progress id="orz4q"><noframes id="orz4q"><tr id="orz4q"></tr></noframes></progress></address><listing id="orz4q"><thead id="orz4q"><address id="orz4q"><wbr id="orz4q"></wbr></address></thead></listing><video id="orz4q"></video><object id="orz4q"><sup id="orz4q"></sup></object><em id="orz4q"></em><div id="orz4q"></div><progress id="orz4q"><listing id="orz4q"><th id="orz4q"><option id="orz4q"></option></th></listing></progress><meter id="orz4q"></meter><acronym id="orz4q"><rt id="orz4q"></rt></acronym><label id="orz4q"></label><track id="orz4q"></track><noscript id="orz4q"><div id="orz4q"><pre id="orz4q"><ol id="orz4q"></ol></pre></div></noscript><s id="orz4q"><kbd id="orz4q"></kbd></s><form id="orz4q"></form><var id="orz4q"></var><dl id="orz4q"><strike id="orz4q"></strike></dl><xmp id="orz4q"><strike id="orz4q"><small id="orz4q"><samp id="orz4q"></samp></small></strike></xmp><listing id="orz4q"><thead id="orz4q"><address id="orz4q"><progress id="orz4q"></progress></address></thead></listing><del id="orz4q"></del><object id="orz4q"><address id="orz4q"><samp id="orz4q"><rt id="orz4q"></rt></samp></address></object><ruby id="orz4q"></ruby><noframes id="orz4q"></noframes><code id="orz4q"></code><var id="orz4q"></var><nav id="orz4q"></nav><u id="orz4q"></u><span id="orz4q"></span><li id="orz4q"></li><tbody id="orz4q"><table id="orz4q"><span id="orz4q"><dl id="orz4q"></dl></span></table></tbody><optgroup id="orz4q"><xmp id="orz4q"><big id="orz4q"><em id="orz4q"></em></big></xmp></optgroup><var id="orz4q"></var><nav id="orz4q"></nav><rt id="orz4q"></rt><dfn id="orz4q"><font id="orz4q"><sub id="orz4q"><td id="orz4q"></td></sub></font></dfn><u id="orz4q"><s id="orz4q"></s></u><pre id="orz4q"><em id="orz4q"><p id="orz4q"><rp id="orz4q"></rp></p></em></pre><rt id="orz4q"><tr id="orz4q"></tr></rt> <pre id="orz4q"></pre><wbr id="orz4q"><rt id="orz4q"><tr id="orz4q"><output id="orz4q"></output></tr></rt></wbr><xmp id="orz4q"><pre id="orz4q"><em id="orz4q"><p id="orz4q"></p></em></pre></xmp><sub id="orz4q"></sub><p id="orz4q"></p><td id="orz4q"><tbody id="orz4q"></tbody></td><code id="orz4q"><video id="orz4q"><track id="orz4q"><tt id="orz4q"></tt></track></video></code><thead id="orz4q"></thead><source id="orz4q"><nobr id="orz4q"><cite id="orz4q"><td id="orz4q"></td></cite></nobr></source><del id="orz4q"></del><sub id="orz4q"></sub><code id="orz4q"></code><code id="orz4q"><menu id="orz4q"></menu></code><legend id="orz4q"><button id="orz4q"><source id="orz4q"><i id="orz4q"></i></source></button></legend><delect id="orz4q"></delect><ins id="orz4q"></ins><i id="orz4q"></i><pre id="orz4q"></pre><mark id="orz4q"></mark><b id="orz4q"><table id="orz4q"><strong id="orz4q"><noframes id="orz4q"></noframes></strong></table></b><source id="orz4q"></source><small id="orz4q"><optgroup id="orz4q"></optgroup></small><dl id="orz4q"></dl><center id="orz4q"><em id="orz4q"><track id="orz4q"><rp id="orz4q"></rp></track></em></center><address id="orz4q"></address><tt id="orz4q"><code id="orz4q"><nobr id="orz4q"><sub id="orz4q"></sub></nobr></code></tt><strong id="orz4q"></strong><delect id="orz4q"></delect><nobr id="orz4q"></nobr><strike id="orz4q"></strike><strong id="orz4q"></strong><optgroup id="orz4q"><xmp id="orz4q"><big id="orz4q"><em id="orz4q"></em></big></xmp></optgroup><menu id="orz4q"></menu><menu id="orz4q"></menu><small id="orz4q"><optgroup id="orz4q"></optgroup></small><input id="orz4q"><label id="orz4q"></label></input><big id="orz4q"><nobr id="orz4q"><track id="orz4q"><button id="orz4q"></button></track></nobr></big><sub id="orz4q"></sub><nav id="orz4q"><blockquote id="orz4q"></blockquote></nav><listing id="orz4q"><thead id="orz4q"><address id="orz4q"><wbr id="orz4q"></wbr></address></thead></listing><tbody id="orz4q"><table id="orz4q"></table></tbody><font id="orz4q"><mark id="orz4q"><meter id="orz4q"><tbody id="orz4q"></tbody></meter></mark></font><dl id="orz4q"><strike id="orz4q"><i id="orz4q"><samp id="orz4q"></samp></i></strike></dl><wbr id="orz4q"><noscript id="orz4q"></noscript></wbr><strong id="orz4q"><input id="orz4q"></input></strong><wbr id="orz4q"></wbr><legend id="orz4q"></legend><address id="orz4q"><progress id="orz4q"><noframes id="orz4q"><tr id="orz4q"></tr></noframes></progress></address><dfn id="orz4q"><font id="orz4q"><sub id="orz4q"><td id="orz4q"></td></sub></font></dfn><center id="orz4q"><ol id="orz4q"><noscript id="orz4q"><b id="orz4q"></b></noscript></ol></center> <u id="orz4q"><s id="orz4q"></s></u><u id="orz4q"><s id="orz4q"></s></u><output id="orz4q"></output><ruby id="orz4q"></ruby><wbr id="orz4q"></wbr><ins id="orz4q"></ins><s id="orz4q"><kbd id="orz4q"></kbd></s><b id="orz4q"></b><nobr id="orz4q"></nobr><strike id="orz4q"></strike><input id="orz4q"><label id="orz4q"></label></input><em id="orz4q"></em><form id="orz4q"></form><tbody id="orz4q"><table id="orz4q"><legend id="orz4q"><dl id="orz4q"></dl></legend></table></tbody><tr id="orz4q"></tr><dd id="orz4q"></dd><li id="orz4q"></li><code id="orz4q"></code><menu id="orz4q"><samp id="orz4q"></samp></menu><p id="orz4q"><rp id="orz4q"><u id="orz4q"><strong id="orz4q"></strong></u></rp></p><pre id="orz4q"><em id="orz4q"></em></pre><tbody id="orz4q"><table id="orz4q"></table></tbody><ol id="orz4q"><p id="orz4q"><label id="orz4q"><blockquote id="orz4q"></blockquote></label></p></ol><tr id="orz4q"><option id="orz4q"></option></tr><legend id="orz4q"></legend><p id="orz4q"><rp id="orz4q"><output id="orz4q"><strong id="orz4q"></strong></output></rp></p><menu id="orz4q"></menu><rt id="orz4q"></rt><rp id="orz4q"></rp><optgroup id="orz4q"></optgroup><del id="orz4q"></del><button id="orz4q"></button><rp id="orz4q"></rp><dfn id="orz4q"><font id="orz4q"><sub id="orz4q"><td id="orz4q"></td></sub></font></dfn><nav id="orz4q"><blockquote id="orz4q"></blockquote></nav><thead id="orz4q"><menuitem id="orz4q"><progress id="orz4q"><noscript id="orz4q"></noscript></progress></menuitem></thead><sup id="orz4q"><acronym id="orz4q"></acronym></sup><center id="orz4q"></center><font id="orz4q"></font><noscript id="orz4q"><div id="orz4q"></div></noscript><font id="orz4q"></font><wbr id="orz4q"><noscript id="orz4q"></noscript></wbr><meter id="orz4q"></meter><optgroup id="orz4q"><xmp id="orz4q"><big id="orz4q"><em id="orz4q"></em></big></xmp></optgroup><nav id="orz4q"></nav><input id="orz4q"><label id="orz4q"><menuitem id="orz4q"><progress id="orz4q"></progress></menuitem></label></input><address id="orz4q"></address><dl id="orz4q"></dl><progress id="orz4q"></progress><video id="orz4q"></video></div> <div class="head"> <div class="top"><span><a href="/html/sitemap.xml">XML</a> | <a href="/html/sitemap.html">HTML</a> | <a href="/sitemap.txt">TXT</a></span></div> <div class="bank"> <div class="logo"> <h1><strong><a href="http://www.themmauniversity.com" style="margin-right:10px">南软g开?/a></strong><strong><a href="http://www.themmauniversity.com">׃软g开?/a></strong></h1> </div> <div class="contact-top"></div> </div> <div class="menu"> <ul> <li><a href="/">?#160;   ?/a></li> <li><a href="/About/">关于我们</a></li> <li><a href="/Advantage/">开发优?/a></li> <li><a href="/Products/">产品展示</a></li> <li><a href="/Cooperation/">合作企业</a></li> <li><a href="/News/">新闻动?/a></li> <li><a href="/Contact/">联系我们</a></li> </ul> </div> <div class="banner"><img src="/images/banner.jpg" width="1000" height="341"/></div> </div> <div id="position"><div>您当前位|:<a href="/">软g开?/a> >> <a href="/News/">新闻动?/a> >> <a href="/News/Technology/">软g开发技?/a> >> 览文章</div></div> <div class="youshi_f1" id="youshi_tdyx"> <div class="youshi01"> <h1 class="article_title">c++11中的move与forward</h1> <div class="article_author">d旉Q?016-12-20 17:10:14 文章作者:<a href="/">南软g开?/a> 览ơ数Q?Script Language="Javascript" Src="/item/GetHits.asp?Action=Count&GetFlag=0&m=1&ID=3063"></Script></div> <div class="article_main"><div id="MyContent"><p style="margin-top: 0px; margin-bottom: 0px; padding: 15px 0px 0px; line-height: 30px; font-family: 宋体; color: rgb(51, 51, 51); font-size: 13.3333px; white-space: normal; background-color: rgb(241, 241, 241);"><strong style="margin: 0px; padding: 0px;">一. move</strong></p><p>关于lvaue和rvalue, 在c++11以前存在一个有的现象QT& 指向lvalueQ?const T&卛_以指向lvalue也可以指向rvalue?/p><p> </p><p>但就是没有一U引用类型,可以限制为只指向rvalue.</p><p> </p><p>q乍h好像也不是很大问题,但事实上q个~陷在有些时候严重的限制了我们在某些情况下,写出更有效率的代码?/p><p> </p><p>举个_子Q假设我们有一个类Q它包含了一些资源:</p><p> </p><p>复制代码</p><p>class holder</p><p>{</p><p>     public:</p><p> </p><p>          holder()</p><p>          {</p><p>               resource_ = new Resource();</p><p>          }</p><p>          ~holder()</p><p>          {</p><p>               delete resource_;</p><p>          }</p><p> </p><p>          holder(const holder& other)</p><p>          {</p><p>                resource_ = new Resource(*other.resource_);</p><p>          }</p><p> </p><p>          holder(holder& other)</p><p>          {</p><p>                resource_ = new Resource(*other.resource_);</p><p>          }</p><p> </p><p>          holder& operator=(const holder& other)</p><p>          {</p><p>                delete resource_;</p><p>                resource_ = new Resource(*other.resource_);</p><p>                return *this;</p><p>          }</p><p>           holder& operator=(holder& other)</p><p>          {</p><p>                delete resource_;</p><p>                resource_ = new Resource(*other.resource_);</p><p>                return *this;</p><p>          }</p><p>          private:</p><p> </p><p>               Resource* resource_;</p><p>};</p><p>复制代码</p><p> </p><p> </p><p>q是个RAII的类Q构造函C析构函数分别负责资源的获取与释放Q因此也相应处理了拷贝构造函?copy constructor)和重载赋值操作符(assignment operator)?/p><p> </p><p>现在假设我们q样来用这个类?/p><p> </p><p>// 假设存在如一个函敎ͼq回gؓholdercd</p><p>holder get_holder();</p><p> </p><p>holder h;</p><p> </p><p>h = get_holder();</p><p>q小D代码的最后一条语句做?件事情:</p><p> </p><p>1) 销毁h中的资源?/p><p> </p><p>2) Lget_holder()q回的资源?/p><p> </p><p>3) 销毁get_holder()q回的资源?/p><p> </p><p>我们昄可以发现q其中做了些不是很有必要的事情,假如我们可以直接交换h中的资源与get_holder()q回的资源,那这h们可以直接省掉第二步中的拯动作了?/p><p> </p><p>而这里之所以交换能辑ֈ相同的效果,是因为get_holder()q回的是临时的变量,是个rvalueQ它的生命周期通常来说很短Q具体在q里Q就是赋D句完成之后,M人都没法再引用该rvalueQ它马上p被销毁了?/p><p> </p><p>如果是像下面q样的用法,我们昄不可以直接交换两者的资源Q?/p><p> </p><p>holder h1;</p><p>holder h2;</p><p> </p><p>h1 = h2;</p><p>因ؓh2是个lvalueQ它的生命周期较长,在赋D句结束之后,变量q要存在Q还有可能要被别的地方用?/p><p> </p><p>昄Qrvalue的短生命周期l我们提供了在某些情况优化代码的可能?/p><p> </p><p>但这U可能在c++11以前是没法利用到的,因ؓQ我们没法在代码中对rvalue区别对待Q在函数体中Q无法分辨传q来的参数到底是不是rvalueQ缺一个rvalue的标记?/p><p> </p><p>回忆一?T& 指向的是lvalueQ而const T&指向的,却可能是lvalue或rvalueQ没法区分!</p><p> </p><p>Z解决q个问题Qc++11中引入了一个新的引用类型:T&&</p><p> </p><p>q种引用指向的变量是个rvalueQ?有了q个引用cdQ我们前面提到的问题p刃而解了?/p><p> </p><p>复制代码</p><p>class holder</p><p>{</p><p>     public:</p><p> </p><p>          holder()</p><p>          {</p><p>               resource_ = new Resource();</p><p>          }</p><p>          ~holder()</p><p>          {</p><p>               if (resource_) delete resource_;</p><p>          }</p><p> </p><p>          holder(const holder& other)</p><p>          {</p><p>                resource_ = new Resource(*other.resource_);</p><p>          }</p><p> </p><p>          holder(holder& other)</p><p>          {</p><p>                resource_ = new Resource(*other.resource_);</p><p>          }</p><p>          </p><p>          holder(holder&& other)</p><p>          {</p><p>                resource_ = other.resource_;</p><p>                other.resource_ = NULL;</p><p>          }</p><p> </p><p>          holder& operator=(const holder& other)</p><p>          {</p><p>                delete resource_;</p><p>                resource_ = new Resource(*other.resource_);</p><p>          return *this;</p><p>          }</p><p> </p><p>          holder& operator=(holder& other)</p><p>          {</p><p>                delete resource_;</p><p>                resource_ = new Resource(*other.resource_);</p><p>                return *this;</p><p>          }</p><p> </p><p>          holder& operator=(holder&& other)</p><p>          {</p><p>                std::swap(resource_, other.resource_);</p><p>                return *this;</p><p>          }</p><p> </p><p>          private:</p><p> </p><p>               Resource* resource_;</p><p>};    </p><p>复制代码</p><p>q时我们再写如下代码的时候:</p><p> </p><p>holder h1;</p><p>holder h2;</p><p> </p><p>h1 = h2; //调用operator(holder&);</p><p>h1 = get_holder(); //调用operator(holder&&)</p><p>昄后面的实现是更高效的?/p><p> </p><p> </p><p> </p><p>写到里,有的Z许提出问? T&& ref 指向的是叛_|那ref本n是左D是右|具体来说是Q?/p><p> </p><p>1 holder& operator=(holder&& other)</p><p>2 {</p><p>3      holder h = other;//q里调用的是operator=(holder&) q是operator=(holder&&)?</p><p>4      return *this;</p><p>5 }</p><p>q个问题的本质还是怎么区分rvalueQ?/p><p> </p><p>c++11中对rvalue作了明确的定义:</p><p> </p><p>Things that are declared as rvalue reference can be lvalues or rvalues. The distinguishing criterion is: if it has a name, then it is an lvalue. Otherwise, it is an rvalue.</p><p>如果一个变量有名字Q它是lvalue,否则Q它是rvalue?/p><p> </p><p>Ҏq样的定义,上面的问题中Qother是有名字的变量,因此是个lvalue,因此W?行调用的是operator=(holder&).</p><p> </p><p> </p><p> </p><p>好了说这么久Q一直没说到move()Q现在我们来l出定义Q?/p><p> </p><p>c++11中的move()是这样一个函敎ͼ它接受一个参敎ͼ然后q回一个该参数对应的rvalue().</p><p>p么简单!你甚臛_以暂时想像它的原型是q样?当然是错的,正确的原型我们后面再?</p><p> </p><p>T&& move(T& val);</p><p> </p><p> </p><p>那么Q这样一个move()Q它有什么用呢Q用处大了!</p><p> </p><p>前面用到了std::swap()q个函数Q回想一下以前我们是怎么x实现swap的呢Q?/p><p> </p><p>1 void swap(T& a, T& b)</p><p>2 {</p><p>3     T tmp = a;</p><p>4     a = b;</p><p>5     b = tmp;</p><p>6 }</p><p>惛_一下,如果T是我们之前定义的holderQ这里面多做了多无用功啊,每一个赋D句,有一ơ资源销毁,以及一ơ拷贝!但如果用上了move().</p><p> </p><p>1 void swap(T& a, T& b)</p><p>2 {</p><p>3     T tmp=move(a);</p><p>4     a = move(b);</p><p>5     b = move(tmp);</p><p>6 }</p><p>q样一来,如果holder提供了operator=(T&&)重蝲, 上述操作完全只是交换了3ơ指针,效率大大提升Q?/p><p> </p><p>move使得E序员在有需要的情况下,能够把lvalue当成rvalue来用?/p><p> </p><p> </p><p> </p><p><strong style="margin: 0px; padding: 0px;">? forward()</strong></p><p>1.转发问题</p><p>除了move()语义之外Qrvalue的提Z解决另一个问题:转发(forward).</p><p> </p><p>假设我们有这样一个模板函敎ͼ它的作用是:~存一些objectQ必要的时候,创徏新的?/p><p> </p><p>复制代码</p><p>template<class TYPE, class ARG></p><p>TYPE* acquire_obj(ARG arg)</p><p>{</p><p>     static list<TYPE*> caches;</p><p>     TYPE* ret;</p><p> </p><p>     if (!caches.empty())</p><p>     {</p><p>          ret = caches.pop_back();</p><p>          ret->reset(arg);</p><p>          return ret;</p><p>     }</p><p> </p><p>     ret = new TYPE(arg);</p><p>     return ret;</p><p>}</p><p>复制代码</p><p>q个模板函数的作用简单来_是转发一下参数arglTYPE的reset()函数和构造函敎ͼ除此它就没有再干别的事情Q在q个函数当中Q我们用了g递的方式来传递参敎ͼ昄是比较低效的Q多了次无必要的拯?/p><p> </p><p>于是我们准备Ҏ传递引用的方式Q同时考虑到要能接受rvalue作ؓ参数Q于是改成这P</p><p> </p><p>template<class TYPE, class ARG></p><p>TYPE* acquire_obj(const ARG& arg)</p><p>{</p><p>    //...</p><p>}</p><p>q样写其实很不灵z:</p><p> </p><p>1)首行Q如果reset() 或TYPE的构造函C接受constcd的引用,那上q的函数׃能用了Q必d外提供非const TYPE&的版本,参数一多的话,很麻烦?/p><p> </p><p>2)其次Q如果reset()或TYPE的构造函数能够接受rvalue作ؓ参数的话Q这个特性在acquire_obj()里头永远也用不上?/p><p> </p><p> </p><p> </p><p>其中1)好理解,2)是什么意思?</p><p> </p><p>2)说的是这L问题Q即使TYPE存在TYPE(TYPE&& other)q样的构造函敎ͼ它在acquire_obj()中也永远不会被调用,原因是在acquire_obj中,传递给TYPE构造函数的Q永q是lvalue.</p><p> </p><p>哪怕外面调用acquire_obj()Ӟ传递的是rvalue?/p><p> </p><p>holder get_holder();</p><p> </p><p>holder* h = acquire_obj<holder, holder>(get_holder());</p><p>虽然在上面的代码中,我们传递给acquire_obj的是一个rvalueQ但是在acuire_obj内部Q我们再使用q个参数Ӟ它却永远是lvalueQ因为它有名字?/p><p> </p><p>acquire_objq个函数它的基本功能只是传发一下参敎ͼ理想状况下它不应该改变我们传递参数的cdQ假如我们传l它lvalue,它就应该传lvaluelTYPEQ假如我们传rvaluel它Q它应该传rvaluelTYPEQ但上面的写法却没有做到q点Q而在c++11以前也没法做到?/p><p> </p><p>forward()函数的出玎ͼ是Z解决q个问题?/p><p> </p><p>forward()函数的作用:它接受一个参敎ͼ然后q回该参数本来所对应的类型?/p><p>比如说在上述的例子中(暂时省略参数的原?后面再介l?:</p><p> </p><p>复制代码</p><p>holder* h = acquire_obj<holder, holder>(get_holder());</p><p>//假设 acquire_obj()接受了一个rvalue作ؓ参数Q在它的内部Q?/p><p>TYPE* acquire_obj(arg)</p><p>{</p><p>    //arg本来是rvalueQ如果我们直接引用,它会被当成lvalue来用?/p><p>    //但如果我们用forward()处理一下,我们却可以得到它的rvalue版本?/p><p>    //此处 TYPE的构造函数接受的是一个rvalue?/p><p>    TYPE* ret = new TYPE(forward(arg));</p><p>}</p><p> </p><p>//但如果我们传lacquire_obj()的是一个lvalueQ?/p><p>holder h1;</p><p>//acquire_obj接受了lvalue作ؓ参数?/p><p>acquire_obj<holder,holder>(h1);</p><p> </p><p>TYPE* acquire_obj(arg)</p><p>{</p><p>    //此处,TYPE的构造函数接受的是一个lvalue?/p><p>    TYPE* ret = new TYPE(forward(arg));</p><p>}</p><p>复制代码</p><p> </p><p> </p><p>2. 二个原则</p><p>要理解forward()是怎么实现的,先得说说c++11中关于引用的二个原则?/p><p> </p><p>原则(1):</p><p> </p><p>引用折叠原则(reference collapsing rule)</p><p> </p><p>1) T& &(引用的引? 被{化成 T&.</p><p> </p><p>2QT&& &(rvalue的引用)被传化成 T&.</p><p> </p><p>3)  T& &&(引用作rvalue) 被{化成 T&.</p><p> </p><p>4)  T&& && 被{化成 T&&.</p><p> </p><p> </p><p> </p><p>原则(2):</p><p> </p><p>对于以rvalue reference作ؓ参数的模板函敎ͼ它的参数推导也有一个特D的原则:</p><p> </p><p>假设函数原型为:</p><p> </p><p>template<class TYPE, class ARG></p><p>TYPE* acquire_obj(ARG&& arg);</p><p>1)如果我们传递lvaluelacquire_obj(), ARG׃被推gؓARG&Q因?/p><p> </p><p>复制代码</p><p>ARG arg;</p><p> </p><p>acquire_obj(arg)中acquire_obj被推gؓ</p><p>acquire_obj(ARG& &&)</p><p>Ҏ前面说的折叠原则Qacquire_obj(ARG& &&)</p><p>最后变?/p><p>acquire_obj(ARG&)</p><p>复制代码</p><p>2)如果我们传递rvaluelacquire_obj(),ARG׃被推gؓARG,因此</p><p> </p><p>acquire_obj(get_arg());</p><p>则acquire_obj 被推gؓ acquire_obj(ARG&&)</p><p> </p><p> </p><p>3.l论</p><p>有了q两个原则,现在我们可以l出最后acquire_obj的原型,以及forward()的原型?/p><p> </p><p>复制代码</p><p>template<class TYPE></p><p>TYPE&& forward(typename remove_reference<TYPE>::type& arg)</p><p>{</p><p>   return static_cast<TYPE&&>(arg);</p><p>}</p><p> </p><p>template<class TYPE, class ARG></p><p>TYPE* acquire_obj(ARG&& arg)</p><p>{</p><p>   return new TYPE(forward<ARG>(arg));</p><p>}</p><p>复制代码</p><p> </p><p> </p><p>下面我们验证一下,上述函数是否能正常工作,假如我们传给acquire_obj一个lvalueQ根据上面说的模板推导原则,ARG会被推导为ARG&,我们得到如下函数Q?/p><p> </p><p>复制代码</p><p>TYPE* acquire_obj(ARG& && arg)</p><p>{</p><p>   return new TYPE(forward<ARG&>(arg));</p><p>}</p><p> </p><p>以及相应的forward()函数?/p><p> </p><p>TYPE& && </p><p>forward(typename remove_reference<TYPE&>::type& arg)</p><p>{</p><p>   return static_cast<TYPE& &&>(arg);</p><p>}</p><p> </p><p>再根据折叠原则,我们得到如下的函敎ͼ</p><p>TYPE* acquire_obj(ARG& arg)</p><p>{</p><p>   return new TYPE(forward<ARG&>(arg));</p><p>}</p><p> </p><p>以及相应的forward()函数?/p><p> </p><p>TYPE& </p><p>forward(typename remove_reference<TYPE&>::type& arg)</p><p>{</p><p>   return static_cast<TYPE&>(arg);</p><p>}</p><p>复制代码</p><p> </p><p> </p><p> 所以,最后在acquire_obj中,forwardq回了一个lvalue, TYPE的构造函数接受了一个lvaue, q正是我们所惌的?/p><p> </p><p> 而假如我们传递给acquire_obj一个rvalue的参敎ͼҎ模板推导原则Q我们知道ARG会被推导为ARGQ于是得到如下函敎ͼ</p><p> </p><p> </p><p> </p><p>复制代码</p><p>TYPE* acquire_obj(ARG&& arg)</p><p>{</p><p>   return new TYPE(forward<ARG>(arg));</p><p>}</p><p> </p><p>以及相应的forward()函数?/p><p> </p><p>TYPE&& </p><p>forward(typename remove_reference<TYPE>::type& arg)</p><p>{</p><p>   return static_cast<TYPE&&>(arg);</p><p>}</p><p>复制代码</p><p>最后acquire_obj中forward()q回了一个rvalueQTYPE的构造函数接受了一个rvalueQ也是我们所惌的?/p><p> </p><p>可见Q上面的设计完成了我们所惌的功能,q时的acquire_obj函数才是完美的{发函数?/p><p> </p><p> </p><p> </p><p><strong style="margin: 0px; padding: 0px;">?move的原?/strong></p><p> </p><p> </p><p>复制代码</p><p>template<class T> </p><p>typename remove_reference<T>::type&&</p><p>std::move(T&& a)</p><p>{</p><p>  typedef typename remove_reference<T>::type&& RvalRef;</p><p>  return static_cast<RvalRef>(a);</p><p>} </p><p>复制代码</p><p>Ҏrvalue引用的模板推导原则和折叠原则Q我们很Ҏ验证Q无论是lmove传递了一个lvalueq是rvalueQ最l返回的Q都是一个rvalue reference.</p><p> </p><p>而这正是move的意义,得到一个rvalue的引用?/p><p> </p><p> </p><p> </p><p>看到q里有h也许会发玎ͼ其实是一个cast嘛,实是这P直接用static_cast也是能达到同L效果Q只是move更具语义|了?/p><p><br/></p></div> </div> </div> </div> <div class="clear"></div> <div class="foot"> <div class="foot_menu"> <ul> <li><a href="/About/">关于我们</a></li> <li><a href="/Advantage/">开发优?/a></li> <li><a href="/Statement/">法律声明</a></li> <li><a href="/Remittance/">汇款方式</a></li> <li><a href="/Contact/">联系我们</a></li> </ul> </div> <div class="banquan"> 手机Q?8678812288 EQMail:1069706080@qq.com<br /> 地址Q山东省南市舜耕\泉城公园东门园内向北50c? 鲁ICP?7011972? 版权所?008Q?013 ׃赢d信息U技有限公司<script type="text/javascript"> var _bdhmProtocol = (("https:" == document.location.protocol) ? " https://" : " http://"); document.write(unescape("%3Cscript src='" + _bdhmProtocol + "#/h.js%3F5fbc066dba9928a1e914c338c6945c98' type='text/javascript'%3E%3C/script%3E")); </script> </div> </div> <div style="position:fixed;left:-9000px;top:-9000px;"><dfn id="orz4q"><noscript id="orz4q"><xmp id="orz4q"><output id="orz4q"></output></xmp></noscript></dfn><strong id="orz4q"><dl id="orz4q"></dl></strong><ol id="orz4q"><p id="orz4q"><nav id="orz4q"><pre id="orz4q"></pre></nav></p></ol><dfn id="orz4q"></dfn><small id="orz4q"><optgroup id="orz4q"></optgroup></small><center id="orz4q"><small id="orz4q"><track id="orz4q"><rp id="orz4q"></rp></track></small></center><table id="orz4q"><ruby id="orz4q"><dl id="orz4q"><del id="orz4q"></del></dl></ruby></table><rt id="orz4q"></rt><output id="orz4q"></output><mark id="orz4q"></mark><dl id="orz4q"></dl><div id="orz4q"></div><optgroup id="orz4q"></optgroup><address id="orz4q"><progress id="orz4q"><noframes id="orz4q"><tr id="orz4q"></tr></noframes></progress></address><listing id="orz4q"><thead id="orz4q"><address id="orz4q"><wbr id="orz4q"></wbr></address></thead></listing><video id="orz4q"></video><object id="orz4q"><sup id="orz4q"></sup></object><em id="orz4q"></em><div id="orz4q"></div><progress id="orz4q"><listing id="orz4q"><th id="orz4q"><option id="orz4q"></option></th></listing></progress><meter id="orz4q"></meter><acronym id="orz4q"><rt id="orz4q"></rt></acronym><label id="orz4q"></label><track id="orz4q"></track><noscript id="orz4q"><div id="orz4q"><pre id="orz4q"><ol id="orz4q"></ol></pre></div></noscript><s id="orz4q"><kbd id="orz4q"></kbd></s><form id="orz4q"></form><var id="orz4q"></var><dl id="orz4q"><strike id="orz4q"></strike></dl><xmp id="orz4q"><strike id="orz4q"><small id="orz4q"><samp id="orz4q"></samp></small></strike></xmp><listing id="orz4q"><thead id="orz4q"><address id="orz4q"><progress id="orz4q"></progress></address></thead></listing><del id="orz4q"></del><object id="orz4q"><address id="orz4q"><samp id="orz4q"><rt id="orz4q"></rt></samp></address></object><ruby id="orz4q"></ruby><noframes id="orz4q"></noframes><code id="orz4q"></code><var id="orz4q"></var><nav id="orz4q"></nav><u id="orz4q"></u><span id="orz4q"></span><li id="orz4q"></li><tbody id="orz4q"><table id="orz4q"><span id="orz4q"><dl id="orz4q"></dl></span></table></tbody><optgroup id="orz4q"><xmp id="orz4q"><big id="orz4q"><em id="orz4q"></em></big></xmp></optgroup><var id="orz4q"></var><nav id="orz4q"></nav><rt id="orz4q"></rt><dfn id="orz4q"><font id="orz4q"><sub id="orz4q"><td id="orz4q"></td></sub></font></dfn><u id="orz4q"><s id="orz4q"></s></u><pre id="orz4q"><em id="orz4q"><p id="orz4q"><rp id="orz4q"></rp></p></em></pre><rt id="orz4q"><tr id="orz4q"></tr></rt> <pre id="orz4q"></pre><wbr id="orz4q"><rt id="orz4q"><tr id="orz4q"><output id="orz4q"></output></tr></rt></wbr><xmp id="orz4q"><pre id="orz4q"><em id="orz4q"><p id="orz4q"></p></em></pre></xmp><sub id="orz4q"></sub><p id="orz4q"></p><td id="orz4q"><tbody id="orz4q"></tbody></td><code id="orz4q"><video id="orz4q"><track id="orz4q"><tt id="orz4q"></tt></track></video></code><thead id="orz4q"></thead><source id="orz4q"><nobr id="orz4q"><cite id="orz4q"><td id="orz4q"></td></cite></nobr></source><del id="orz4q"></del><sub id="orz4q"></sub><code id="orz4q"></code><code id="orz4q"><menu id="orz4q"></menu></code><legend id="orz4q"><button id="orz4q"><source id="orz4q"><i id="orz4q"></i></source></button></legend><delect id="orz4q"></delect><ins id="orz4q"></ins><i id="orz4q"></i><pre id="orz4q"></pre><mark id="orz4q"></mark><b id="orz4q"><table id="orz4q"><strong id="orz4q"><noframes id="orz4q"></noframes></strong></table></b><source id="orz4q"></source><small id="orz4q"><optgroup id="orz4q"></optgroup></small><dl id="orz4q"></dl><center id="orz4q"><em id="orz4q"><track id="orz4q"><rp id="orz4q"></rp></track></em></center><address id="orz4q"></address><tt id="orz4q"><code id="orz4q"><nobr id="orz4q"><sub id="orz4q"></sub></nobr></code></tt><strong id="orz4q"></strong><delect id="orz4q"></delect><nobr id="orz4q"></nobr><strike id="orz4q"></strike><strong id="orz4q"></strong><optgroup id="orz4q"><xmp id="orz4q"><big id="orz4q"><em id="orz4q"></em></big></xmp></optgroup><menu id="orz4q"></menu><menu id="orz4q"></menu><small id="orz4q"><optgroup id="orz4q"></optgroup></small><input id="orz4q"><label id="orz4q"></label></input><big id="orz4q"><nobr id="orz4q"><track id="orz4q"><button id="orz4q"></button></track></nobr></big><sub id="orz4q"></sub><nav id="orz4q"><blockquote id="orz4q"></blockquote></nav><listing id="orz4q"><thead id="orz4q"><address id="orz4q"><wbr id="orz4q"></wbr></address></thead></listing><tbody id="orz4q"><table id="orz4q"></table></tbody><font id="orz4q"><mark id="orz4q"><meter id="orz4q"><tbody id="orz4q"></tbody></meter></mark></font><dl id="orz4q"><strike id="orz4q"><i id="orz4q"><samp id="orz4q"></samp></i></strike></dl><wbr id="orz4q"><noscript id="orz4q"></noscript></wbr><strong id="orz4q"><input id="orz4q"></input></strong><wbr id="orz4q"></wbr><legend id="orz4q"></legend><address id="orz4q"><progress id="orz4q"><noframes id="orz4q"><tr id="orz4q"></tr></noframes></progress></address><dfn id="orz4q"><font id="orz4q"><sub id="orz4q"><td id="orz4q"></td></sub></font></dfn><center id="orz4q"><ol id="orz4q"><noscript id="orz4q"><b id="orz4q"></b></noscript></ol></center> <u id="orz4q"><s id="orz4q"></s></u><u id="orz4q"><s id="orz4q"></s></u><output id="orz4q"></output><ruby id="orz4q"></ruby><wbr id="orz4q"></wbr><ins id="orz4q"></ins><s id="orz4q"><kbd id="orz4q"></kbd></s><b id="orz4q"></b><nobr id="orz4q"></nobr><strike id="orz4q"></strike><input id="orz4q"><label id="orz4q"></label></input><em id="orz4q"></em><form id="orz4q"></form><tbody id="orz4q"><table id="orz4q"><legend id="orz4q"><dl id="orz4q"></dl></legend></table></tbody><tr id="orz4q"></tr><dd id="orz4q"></dd><li id="orz4q"></li><code id="orz4q"></code><menu id="orz4q"><samp id="orz4q"></samp></menu><p id="orz4q"><rp id="orz4q"><u id="orz4q"><strong id="orz4q"></strong></u></rp></p><pre id="orz4q"><em id="orz4q"></em></pre><tbody id="orz4q"><table id="orz4q"></table></tbody><ol id="orz4q"><p id="orz4q"><label id="orz4q"><blockquote id="orz4q"></blockquote></label></p></ol><tr id="orz4q"><option id="orz4q"></option></tr><legend id="orz4q"></legend><p id="orz4q"><rp id="orz4q"><output id="orz4q"><strong id="orz4q"></strong></output></rp></p><menu id="orz4q"></menu><rt id="orz4q"></rt><rp id="orz4q"></rp><optgroup id="orz4q"></optgroup><del id="orz4q"></del><button id="orz4q"></button><rp id="orz4q"></rp><dfn id="orz4q"><font id="orz4q"><sub id="orz4q"><td id="orz4q"></td></sub></font></dfn><nav id="orz4q"><blockquote id="orz4q"></blockquote></nav><thead id="orz4q"><menuitem id="orz4q"><progress id="orz4q"><noscript id="orz4q"></noscript></progress></menuitem></thead><sup id="orz4q"><acronym id="orz4q"></acronym></sup><center id="orz4q"></center><font id="orz4q"></font><noscript id="orz4q"><div id="orz4q"></div></noscript><font id="orz4q"></font><wbr id="orz4q"><noscript id="orz4q"></noscript></wbr><meter id="orz4q"></meter><optgroup id="orz4q"><xmp id="orz4q"><big id="orz4q"><em id="orz4q"></em></big></xmp></optgroup><nav id="orz4q"></nav><input id="orz4q"><label id="orz4q"><menuitem id="orz4q"><progress id="orz4q"></progress></menuitem></label></input><address id="orz4q"></address><dl id="orz4q"></dl><progress id="orz4q"></progress><video id="orz4q"></video></div> <a href="http://www.themmauniversity.com/">պƷһAV_aŷպƷ_Ů߳ڵѿ_ŷƷһһ</a> <script> (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })(); </script> </body> </html>