??xml version="1.0" encoding="utf-8" standalone="yes"?>久久99国产精一区二区三区,国产精品激情综合久久,狠狠人妻久久久久久综合http://www.shnenglu.com/kesalin/category/3832.htmlx嵌入式操作系l,Udq_Q图形开发?lt;a target="_top">-->加微?^_^</a>zh-cnThu, 10 Jul 2014 19:03:32 GMTThu, 10 Jul 2014 19:03:32 GMT60如何在遍历中使用 iterator/reverse_iterator 删除元素http://www.shnenglu.com/kesalin/archive/2014/07/10/cpp_stl.html|朝?/dc:creator>|朝?/author>Thu, 10 Jul 2014 01:42:00 GMThttp://www.shnenglu.com/kesalin/archive/2014/07/10/cpp_stl.htmlhttp://www.shnenglu.com/kesalin/comments/206672.htmlhttp://www.shnenglu.com/kesalin/archive/2014/07/10/cpp_stl.html#Feedback1http://www.shnenglu.com/kesalin/comments/commentRss/206672.htmlhttp://www.shnenglu.com/kesalin/services/trackbacks/206672.html首先Q要明白使用正向q代器(iteratorQ进行反向遍历是错误的用法,要不q嘛要有反向q代器呢Qreverse_iteratorQ。其ơ,Ҏ(gu)容器的特性,遍历删除操作的用法可以分Zl,W一l是 list ?vectorQ第二组?map ?set?nbsp; 阅读全文

]]>
让gcc支持成员函数模板的trickhttp://www.shnenglu.com/kesalin/archive/2013/07/12/gcc_member_function_template.html|朝?/dc:creator>|朝?/author>Fri, 12 Jul 2013 14:04:00 GMThttp://www.shnenglu.com/kesalin/archive/2013/07/12/gcc_member_function_template.htmlhttp://www.shnenglu.com/kesalin/comments/201753.htmlhttp://www.shnenglu.com/kesalin/archive/2013/07/12/gcc_member_function_template.html#Feedback2http://www.shnenglu.com/kesalin/comments/commentRss/201753.htmlhttp://www.shnenglu.com/kesalin/services/trackbacks/201753.html让gcc支持成员函数模板的trick

|朝?(http://www.shnenglu.com/kesalin/)

gcc 4.7.3 不支持成员函数模板特化。如下代码:

#ifndef __MEMFUNTEMPLATE_H__
#define __MEMFUNTEMPLATE_H__

#include <stdio.h>

class Base {};
class Derived : public Base {};

struct Functor {
    template <typename T> void function() {
        printf(" Primary template.\n");
    }

    template<>
    void function<int>(){
        printf(" Specialization for int.\n");
    }

    template<> void function<Base *>() {
        printf(" Specialization for Base *.\n");
    }
};

class Tester {
public:
    static void DoTest()
    {
        Functor functor;
        functor.function<char>();
        functor.function<int>();
        functor.function<Base *>();
        functor.function<Derived *>();
    }
};

#endif // __MEMFUNTEMPLATE_H__

?VS2010 中编译运行是没有问题的,但在 gcc 4.7.3下,~译都通不q:


Z辑ֈq似成员函数模板特化的效果,可以利用成员函数L板以及重载函数来实现Q?br />


/*
 * MemFunTemplate.h
 *
 *  Created on: Jul 12, 2013
 *      Author: http://blog.csdn.net/kesalin/
 */

#ifndef MEMFUNTEMPLATE_H_
#define MEMFUNTEMPLATE_H_
#include <stdio.h>
template<typename T>
struct DummyIdentity {
    typedef T type;
};
class Base {};
class Derived : public Base {};
struct Functor {
    template <typename T> void function() {
        function(DummyIdentity<T>());
    }
private:
    template <typename T>
    void function(DummyIdentity<T>) {
        printf(" Primary template DummyIdentity<T>.\n");
    }
    void function(DummyIdentity<int>) {
        printf(" overload function for DummyIdentity<int>.\n");
    }
    void function(DummyIdentity<Base *>) {
        printf(" overload function for DummyIdentity<Base *>.\n");
    }
};
class Tester {
public:
    static void DoTest()
    {
        Functor functor;
        functor.function<char>();
        functor.function<int>();
        functor.function<Base *>();
        functor.function<Derived *>();
    }
};
#endif /* MEMFUNTEMPLATE_H_ */


调用 DoTest() q行l果如下Q?/p>


注意Q?/span>

VS2010 版本的代码,模板形参?TQ在实例化不会进行隐式类型{换。即?nbsp;Derived * 当作实参调用的是L板,而不?Base * 特化版本

而在 gcc  下,模板形参虽然也ؓTQ但影响重蝲册?function 参数为:DummyIdentity<T>Q用不同的实际参数实例化该模板,得到的是一堆重载函数。因此用 Derived * 当作实参Ӟ调用的函数自然就是实例化?nbsp;void function(DummyIdentity<T>)了?/p>



]]>
[深入理解C++Q二Q]理解接口l承规则http://www.shnenglu.com/kesalin/archive/2012/11/06/interface_inherit.html|朝?/dc:creator>|朝?/author>Tue, 06 Nov 2012 13:21:00 GMThttp://www.shnenglu.com/kesalin/archive/2012/11/06/interface_inherit.htmlhttp://www.shnenglu.com/kesalin/comments/194777.htmlhttp://www.shnenglu.com/kesalin/archive/2012/11/06/interface_inherit.html#Feedback5http://www.shnenglu.com/kesalin/comments/commentRss/194777.htmlhttp://www.shnenglu.com/kesalin/services/trackbacks/194777.htmlQ一Q,C++ 虚函数表解析
Q二Q,C++ 对象的内存布局Q上Q?
Q三Q,C++ 对象的内存布局Q下Q?

在l阅L文之前,先阅读这三篇文章Q以更好地理解本pd文章。在接下来的内容中,我将从重载,重写Q屏蔽等概念入手Q引入众多接口承规则?nbsp; 阅读全文

]]>
[深入理解C++Q一Q]cd转换QType CastingQ?/title><link>http://www.shnenglu.com/kesalin/archive/2012/10/28/type_cast.html</link><dc:creator>|朝?/dc:creator><author>|朝?/author><pubDate>Sun, 28 Oct 2012 13:44:00 GMT</pubDate><guid>http://www.shnenglu.com/kesalin/archive/2012/10/28/type_cast.html</guid><wfw:comment>http://www.shnenglu.com/kesalin/comments/193986.html</wfw:comment><comments>http://www.shnenglu.com/kesalin/archive/2012/10/28/type_cast.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.shnenglu.com/kesalin/comments/commentRss/193986.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/kesalin/services/trackbacks/193986.html</trackback:ping><description><![CDATA[     摘要: cd转换是给定类型的表达式{换ؓ另一U类型。C++中的转型可分ZU:隐式cd转换和显式类型{换。下面将详细介绍q两U{型操作,以及各自的适用场景Q潜在问题,最l将ȝ使用cd转换操作应牢记的原则?nbsp; <a href='http://www.shnenglu.com/kesalin/archive/2012/10/28/type_cast.html'>阅读全文</a><img src ="http://www.shnenglu.com/kesalin/aggbug/193986.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/kesalin/" target="_blank">|朝?/a> 2012-10-28 21:44 <a href="http://www.shnenglu.com/kesalin/archive/2012/10/28/type_cast.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>深入分析Sleep(0)与Sleep(1)的区?/title><link>http://www.shnenglu.com/kesalin/archive/2012/10/11/Sleep.html</link><dc:creator>|朝?/dc:creator><author>|朝?/author><pubDate>Thu, 11 Oct 2012 12:04:00 GMT</pubDate><guid>http://www.shnenglu.com/kesalin/archive/2012/10/11/Sleep.html</guid><wfw:comment>http://www.shnenglu.com/kesalin/comments/193183.html</wfw:comment><comments>http://www.shnenglu.com/kesalin/archive/2012/10/11/Sleep.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.shnenglu.com/kesalin/comments/commentRss/193183.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/kesalin/services/trackbacks/193183.html</trackback:ping><description><![CDATA[     摘要: ?timeout = 0Q??Sleep(0)Q如果线E调度器的可q行队列中有大于或等于当前线E优先的就l线E存在,操作pȝ会将当前U程从处理器上移除,调度其他优先U高的就l线E运行;如果可运行队列中的没有就l线E或所有就l线E的优先U均低于当前U程优先U,那么当前U程会l执行,像没有调用 Sleep(0)一栗?<br> <br>?timeout > 0 Ӟ如:Sleep(1)Q会引发U程上下文切换:调用U程会从U程调度器的可运行队列中被移除一D|_q个旉D늺{于 timeout 所指定的时间长度。ؓ什么说U等于呢Q是因ؓ睡眠旉单位为毫U,q与pȝ的时间精度有兟뀂通常情况下,pȝ的时间精度ؓ 10 msQ那么指定Q意少?10 ms但大?0 ms 的睡眠时_均会向上求gؓ 10 ms?nbsp; <a href='http://www.shnenglu.com/kesalin/archive/2012/10/11/Sleep.html'>阅读全文</a><img src ="http://www.shnenglu.com/kesalin/aggbug/193183.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/kesalin/" target="_blank">|朝?/a> 2012-10-11 20:04 <a href="http://www.shnenglu.com/kesalin/archive/2012/10/11/Sleep.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>数学函数备䆾。。?/title><link>http://www.shnenglu.com/kesalin/archive/2010/06/04/math_function.html</link><dc:creator>|朝?/dc:creator><author>|朝?/author><pubDate>Fri, 04 Jun 2010 10:38:00 GMT</pubDate><guid>http://www.shnenglu.com/kesalin/archive/2010/06/04/math_function.html</guid><wfw:comment>http://www.shnenglu.com/kesalin/comments/117183.html</wfw:comment><comments>http://www.shnenglu.com/kesalin/archive/2010/06/04/math_function.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.shnenglu.com/kesalin/comments/commentRss/117183.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/kesalin/services/trackbacks/117183.html</trackback:ping><description><![CDATA[     摘要: 数学函数备䆾。。?nbsp; <a href='http://www.shnenglu.com/kesalin/archive/2010/06/04/math_function.html'>阅读全文</a><img src ="http://www.shnenglu.com/kesalin/aggbug/117183.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/kesalin/" target="_blank">|朝?/a> 2010-06-04 18:38 <a href="http://www.shnenglu.com/kesalin/archive/2010/06/04/math_function.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>【译】VC10中的C++0xҎ(gu)?part 3 : 声明之类?http://www.shnenglu.com/kesalin/archive/2009/06/07/86960.html|朝?/dc:creator>|朝?/author>Sun, 07 Jun 2009 01:28:00 GMThttp://www.shnenglu.com/kesalin/archive/2009/06/07/86960.htmlhttp://www.shnenglu.com/kesalin/comments/86960.htmlhttp://www.shnenglu.com/kesalin/archive/2009/06/07/86960.html#Feedback4http://www.shnenglu.com/kesalin/comments/commentRss/86960.htmlhttp://www.shnenglu.com/kesalin/services/trackbacks/86960.htmlPart 1 Q介l了LambdasQ?赋予新意义的autoQ以?static_assertQ?
Part 2( 一 , ?, ?)Q介l了叛_引用(Rvalue ReferencesQ;
Part 3Q介l了表达式类型(decltypeQ?

VC10中的C++0xҎ(gu)?Part 1,2,3 译文打包下蝲Qdoc ?pdf 格式Q: Ҏ(gu)下蝲

本文是Part 3?nbsp; 阅读全文

]]>
【译】VC10中的C++0xҎ(gu)?Part 2 Q?Q:叛_引?/title><link>http://www.shnenglu.com/kesalin/archive/2009/06/05/86851.html</link><dc:creator>|朝?/dc:creator><author>|朝?/author><pubDate>Fri, 05 Jun 2009 07:09:00 GMT</pubDate><guid>http://www.shnenglu.com/kesalin/archive/2009/06/05/86851.html</guid><wfw:comment>http://www.shnenglu.com/kesalin/comments/86851.html</wfw:comment><comments>http://www.shnenglu.com/kesalin/archive/2009/06/05/86851.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.shnenglu.com/kesalin/comments/commentRss/86851.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/kesalin/services/trackbacks/86851.html</trackback:ping><description><![CDATA[<p> </p> <p style="TEXT-ALIGN: center"><span style="FONT-WEIGHT: bold">【译】VC10中的C++0xҎ(gu)?Part 2 Q?Q:叛_引?/span> <br></p> <p style="TEXT-ALIGN: center">来源Q?a title=vcvlog target=_blank>vcblog</a> 作者:Stephan T. Lavavej 译Q?a title=飘飘白云的C++博客 href="http://www.shnenglu.com/kesalin" target=_blank>飘飘白云</a>   </p> <p style="TEXT-ALIGN: center">(转蝲时请注明作者和出处。未l许可,请勿用于商业用? <br></p> <p>?</p> <div id="1611616" class=postText><style> <!-- /* Font Definitions */ @font-face {font-family:Wingdings; panose-1:5 0 0 0 0 0 0 0 0 0; mso-font-charset:2; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:0 268435456 0 0 -2147483648 0;} @font-face {font-family:"MS Mincho"; panose-1:2 2 6 9 4 2 5 8 3 4; mso-font-alt:"QS 明朝"; mso-font-charset:128; mso-generic-font-family:modern; mso-font-pitch:fixed; mso-font-signature:-1610612033 1757936891 16 0 131231 0;} @font-face {font-family:宋体; panose-1:2 1 6 0 3 1 1 1 1 1; mso-font-alt:SimSun; mso-font-charset:134; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:3 135135232 16 0 262145 0;} @font-face {font-family:Century; panose-1:2 4 6 4 5 5 5 2 3 4; mso-font-charset:0; mso-generic-font-family:roman; mso-font-pitch:variable; mso-font-signature:647 0 0 0 159 0;} @font-face {font-family:"MS PGothic"; panose-1:2 11 6 0 7 2 5 8 2 4; mso-font-charset:128; mso-generic-font-family:swiss; mso-font-pitch:variable; mso-font-signature:-1610612033 1757936891 16 0 131231 0;} @font-face {font-family:Verdana; panose-1:2 11 6 4 3 5 4 4 2 4; mso-font-charset:0; mso-generic-font-family:swiss; mso-font-pitch:variable; mso-font-signature:536871559 0 0 0 415 0;} @font-face {font-family:"\@MS PGothic"; panose-1:2 11 6 0 7 2 5 8 2 4; mso-font-charset:128; mso-generic-font-family:swiss; mso-font-pitch:variable; mso-font-signature:-1610612033 1757936891 16 0 131231 0;} @font-face {font-family:"\@宋体"; panose-1:2 1 6 0 3 1 1 1 1 1; mso-font-charset:134; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:3 135135232 16 0 262145 0;} @font-face {font-family:"\@MS Mincho"; panose-1:2 2 6 9 4 2 5 8 3 4; mso-font-charset:128; mso-generic-font-family:modern; mso-font-pitch:fixed; mso-font-signature:-1610612033 1757936891 16 0 131231 0;} /* Style Definitions */ p.MsoNormal, li.MsoNormal, div.MsoNormal {mso-style-parent:""; margin:0cm; margin-bottom:.0001pt; text-align:justify; text-justify:inter-ideograph; mso-pagination:none; font-size:10.5pt; mso-bidi-font-size:12.0pt; font-family:Century; mso-fareast-font-family:"MS Mincho"; mso-bidi-font-family:"Times New Roman"; mso-font-kerning:1.0pt; mso-fareast-language:JA;} h1 {mso-margin-top-alt:auto; margin-right:0cm; mso-margin-bottom-alt:auto; margin-left:0cm; mso-pagination:widow-orphan; mso-outline-level:1; font-size:24.0pt; font-family:"MS PGothic"; mso-bidi-font-family:"MS PGothic"; mso-fareast-language:JA;} p.MsoHeader, li.MsoHeader, div.MsoHeader {margin:0cm; margin-bottom:.0001pt; text-align:justify; text-justify:inter-ideograph; mso-pagination:none; tab-stops:center 212.6pt right 425.2pt; layout-grid-mode:char; font-size:10.5pt; mso-bidi-font-size:12.0pt; font-family:Century; mso-fareast-font-family:"MS Mincho"; mso-bidi-font-family:"Times New Roman"; mso-font-kerning:1.0pt; mso-fareast-language:JA;} p.MsoFooter, li.MsoFooter, div.MsoFooter {margin:0cm; margin-bottom:.0001pt; text-align:justify; text-justify:inter-ideograph; mso-pagination:none; tab-stops:center 212.6pt right 425.2pt; layout-grid-mode:char; font-size:10.5pt; mso-bidi-font-size:12.0pt; font-family:Century; mso-fareast-font-family:"MS Mincho"; mso-bidi-font-family:"Times New Roman"; mso-font-kerning:1.0pt; mso-fareast-language:JA;} a:link, span.MsoHyperlink {color:blue; text-decoration:underline; text-underline:single;} a:visited, span.MsoHyperlinkFollowed {color:purple; text-decoration:underline; text-underline:single;} /* Page Definitions */ @page {mso-page-border-surround-header:no; mso-page-border-surround-footer:no;} @page Section1 {size:595.3pt 841.9pt; margin:99.25pt 3.0cm 3.0cm 3.0cm; mso-header-margin:42.55pt; mso-footer-margin:49.6pt; mso-paper-source:0; layout-grid:18.0pt;} div.Section1 {page:Section1;} --> </style> <p>q一pd文章介绍Microsoft Visual Studio 2010 中支持的C++ 0xҎ(gu),目前有三部分?<br><a title="VC10中的C++0xҎ(gu)?part 1" target=_blank>Part 1</a> Q介l了LambdasQ?赋予新意义的autoQ以?static_assertQ?<br>Part 2( <a title="VC10中的C++0xҎ(gu)?part 2 W一部分" href="http://www.shnenglu.com/kesalin/archive/2009/05/28/85983.html" target=_blank>一</a> , <a title="VC10中的C++0xҎ(gu)?part 2 W二部分" href="http://www.shnenglu.com/kesalin/archive/2009/06/04/86720.html" target=_blank>?/a> , <a title="VC10中的C++0xҎ(gu)?part 2 W三部分 " href="http://www.shnenglu.com/kesalin/archive/2009/06/05/86851.html" target=_blank>?/a> )Q介l了叛_引用(Rvalue ReferencesQ; <br><a title="VC10中的C++0xҎ(gu)?part 3" href="http://www.shnenglu.com/kesalin/archive/2009/06/07/86960.html" target=_blank>Part 3</a>Q介l了表达式类型(decltypeQ?br><br>VC10中的C++0xҎ(gu)?Part 1,2,3 译文打包下蝲Qdoc ?pdf 格式Q: <a title="VC10中的C++0xҎ(gu)(Part 1,2,3Q译文doc和pdf文档" href="http://www.shnenglu.com/Files/kesalin/Cplusplus0x_in_VC10.zip" target=_blank>Ҏ(gu)下蝲</a></p> </div> <br>本文?Part 2 的第三页 <p> </p> <p> <meta content=Word.Document name=ProgId> <meta content="Microsoft Word 11" name=Generator> <meta content="Microsoft Word 11" name=Originator> <object id=ieooui classid=clsid:38481807-ca0e-42d2-bf39-b33af135cc4d></object><style> st1\:*{behavior:url(#ieooui) } </style><style> <!-- /* Font Definitions */ @font-face {font-family:"QS 明朝"; panose-1:2 2 6 9 4 2 5 8 3 4; mso-font-alt:"MS Mincho"; mso-font-charset:128; mso-generic-font-family:roman; mso-font-pitch:fixed; mso-font-signature:-1610612033 1757936891 16 0 131231 0;} @font-face {font-family:SimSun; panose-1:2 1 6 0 3 1 1 1 1 1; mso-font-alt:宋体; mso-font-charset:134; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:3 135135232 16 0 262145 0;} @font-face {font-family:Century; panose-1:2 4 6 4 5 5 5 2 3 4; mso-font-charset:0; mso-generic-font-family:roman; mso-font-pitch:variable; mso-font-signature:647 0 0 0 159 0;} @font-face {font-family:"QS Qゴ゗?; panose-1:2 11 6 0 7 2 5 8 2 4; mso-font-charset:128; mso-generic-font-family:modern; mso-font-pitch:variable; mso-font-signature:-1610612033 1757936891 16 0 131231 0;} @font-face {font-family:Verdana; panose-1:2 11 6 4 3 5 4 4 2 4; mso-font-charset:0; mso-generic-font-family:swiss; mso-font-pitch:variable; mso-font-signature:536871559 0 0 0 415 0;} @font-face {font-family:"\@QS Qゴ゗?; panose-1:2 11 6 0 7 2 5 8 2 4; mso-font-charset:128; mso-generic-font-family:modern; mso-font-pitch:variable; mso-font-signature:-1610612033 1757936891 16 0 131231 0;} @font-face {font-family:"\@SimSun"; panose-1:2 1 6 0 3 1 1 1 1 1; mso-font-charset:134; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:3 135135232 16 0 262145 0;} @font-face {font-family:"\@QS 明朝"; panose-1:2 2 6 9 4 2 5 8 3 4; mso-font-charset:128; mso-generic-font-family:roman; mso-font-pitch:fixed; mso-font-signature:-1610612033 1757936891 16 0 131231 0;} /* Style Definitions */ p.MsoNormal, li.MsoNormal, div.MsoNormal {mso-style-parent:""; margin:0mm; margin-bottom:.0001pt; text-align:justify; text-justify:inter-ideograph; mso-pagination:none; font-size:10.5pt; mso-bidi-font-size:12.0pt; font-family:Century; mso-fareast-font-family:"QS 明朝"; mso-bidi-font-family:"Times New Roman"; mso-font-kerning:1.0pt;} h1 {mso-margin-top-alt:auto; margin-right:0mm; mso-margin-bottom-alt:auto; margin-left:0mm; mso-pagination:widow-orphan; mso-outline-level:1; font-size:24.0pt; font-family:"QS Qゴ゗?; mso-bidi-font-family:"QS Qゴ゗?; font-weight:bold;} p.MsoHeader, li.MsoHeader, div.MsoHeader {margin:0mm; margin-bottom:.0001pt; text-align:justify; text-justify:inter-ideograph; mso-pagination:none; tab-stops:center 212.6pt right 425.2pt; layout-grid-mode:char; font-size:10.5pt; mso-bidi-font-size:12.0pt; font-family:Century; mso-fareast-font-family:"QS 明朝"; mso-bidi-font-family:"Times New Roman"; mso-font-kerning:1.0pt;} p.MsoFooter, li.MsoFooter, div.MsoFooter {margin:0mm; margin-bottom:.0001pt; text-align:justify; text-justify:inter-ideograph; mso-pagination:none; tab-stops:center 212.6pt right 425.2pt; layout-grid-mode:char; font-size:10.5pt; mso-bidi-font-size:12.0pt; font-family:Century; mso-fareast-font-family:"QS 明朝"; mso-bidi-font-family:"Times New Roman"; mso-font-kerning:1.0pt;} a:link, span.MsoHyperlink {color:blue; text-decoration:underline; text-underline:single;} a:visited, span.MsoHyperlinkFollowed {color:purple; text-decoration:underline; text-underline:single;} p {mso-margin-top-alt:auto; margin-right:0mm; mso-margin-bottom-alt:auto; margin-left:0mm; mso-pagination:widow-orphan; font-size:12.0pt; font-family:"QS Qゴ゗?; mso-bidi-font-family:"QS Qゴ゗?;} span.trans {mso-style-name:trans;} span.apple-style-span {mso-style-name:apple-style-span;} span.apple-converted-space {mso-style-name:apple-converted-space;} p.greentitle, li.greentitle, div.greentitle {mso-style-name:greentitle; mso-margin-top-alt:auto; margin-right:0mm; mso-margin-bottom-alt:auto; margin-left:0mm; mso-pagination:widow-orphan; font-size:12.0pt; font-family:"QS Qゴ゗?; mso-bidi-font-family:"QS Qゴ゗?;} p.inner, li.inner, div.inner {mso-style-name:inner; mso-margin-top-alt:auto; margin-right:0mm; mso-margin-bottom-alt:auto; margin-left:0mm; mso-pagination:widow-orphan; font-size:12.0pt; font-family:"QS Qゴ゗?; mso-bidi-font-family:"QS Qゴ゗?;} /* Page Definitions */ @page {mso-page-border-surround-header:no; mso-page-border-surround-footer:no;} @page Section1 {size:612.0pt 792.0pt; margin:99.25pt 30.0mm 30.0mm 30.0mm; mso-header-margin:36.0pt; mso-footer-margin:36.0pt; mso-paper-source:0;} div.Section1 {page:Section1;} /* List Definitions */ @list l0 {mso-list-id:986742580; mso-list-type:hybrid; mso-list-template-ids:-1336744774 284093962 67698711 67698705 67698703 67698711 67698705 67698703 67698711 67698705;} @list l0:level1 {mso-level-text:%1Q? mso-level-tab-stop:18.0pt; mso-level-number-position:left; margin-left:18.0pt; text-indent:-18.0pt; mso-fareast-font-family:"QS Qゴ゗?;} ol {margin-bottom:0mm;} ul {margin-bottom:0mm;} --> </style><strong>转发问题</strong><br><br>在程序员不用写高度泛化的代码的时候,C++98/03 ?lvalueQ?rvalueQ?引用Q还有模板看h是很完美的。假设你要写一个完全泛化的函数 outer()Q这个函数的目的是将L数目个Q意类型的参数传递(也就?#8220;转发”Q给函数 inner()。已有很多不错的解决Ҏ(gu)Q比?factory 函数 make_shared<T>(args) 是把 args 传给 T 的构造函敎ͼ然后q回 shared_ptr<T>。(q样把 T 对象和用于对它进行引用计数的代码存储到同一块动态内存中Q性能上与侵入式引用计C样好Q; 而像 function<Ret(args)> q样的包装类是把参数传给其内部存储的函数对象QfunctorQ,{等。在q篇文章里,我们只对 outer() 是如何把参数传递给 inner() q部分感兴趣。至?outer() 的返回类型是怎么军_的是另外的问题(有时候很单,?make_shared<T>(args) Lq回 shared_prt<T>Q)Q但要在完全搞定q个问题的一般化情况Q你p用到 C++0x?decltype Ҏ(gu)了Q?/p> <p> </p> <p>如果不带参数Q就不存在这L(fng)问题Q那么带一个参数情况呢Q让我们试写个 outerQ) Q?/p> <p> </p> <p><strong>template <typename T> void outer(T& t) {</strong></p> <p><strong>    inner(t);</strong></p> <p><strong>}</strong></p> <p> </p> <p>?题来了,如果传给它的参数是非帔R rvalueQ那我们无法调?outer()。如?inner() 接收 const int& 型的参数Q那 inner(5) 是可以通过~译的,但是 outer(5) q译不q了。因?T 会被推导?intQ??int& 是不能绑定到帔R 5 的?/p> <p> </p> <p>好吧Q让我们试试q个Q?/p> <p> </p> <p><strong>template <typename T> void outer(const T& t) {</strong></p> <p><strong>    inner(t);</strong></p> <p><strong>}</strong></p> <p> </p> <p>如果 innerQ)接收 int& 型参敎ͼ那就会违?const 正确性,~译都过不了?/p> <p> </p> <p>现在Q你可以重蝲两个分别?T& ?const T& 参数?outerQ)Q这实用。当你调?outerQ)Ӟ像直接调用 innerQ) 一栗?/p> <p> </p> <p>可惜的是Q这中方法在多参数的情况下就ȝ了(译注Q要写的重蝲函数太多了)。你得为每一个参数像 T1& ?const T1&, T2& ?const T2& {这栯行重载,要重载的函数数目呈指数增长。(VC9 SP1 ?tr1Q:bind() 够让h感到l望了,它ؓ 5 个参数这么重载出?63 个函数。如果不q么蛮干的话Q没有像q里的长篏qͼ我们很难跟使用者解释ؓ什么不能调用用 1729 q样?ravlue 做参数的函数。ؓ了生出q些重蝲函数使用了oZ呕的预处理机Ӟ恶心C都不想知道它Q?/p> <p> </p> <p>?C++98/03 中,转发问题是很严重的,而且本质上无解(必须求助于恶心的预处理机Ӟq会严重拖慢~译速度Q还让代码变得难以阅读)。ȝQ?rvalue 优雅地解决了q个问题?/p> <p> </p> <p><strong>完美</strong><strong>转发</strong><strong>Q?/strong><strong> </strong><strong>模式</strong></p> <p> </p> <p>完美转发让你能简单而清晰地只写一个模板函数就可以转发所有的参数lQ意函敎ͼ不管它带几个参数Q也不管参数cd是什么。而且参数的非帔R/帔RQ?lvalue/rvalue 属性都能得以保留,让你可以像?innerQ) 一样?outerQ)Q还可以?move 语意一L(fng)从而获得额外的好处。( C++0x 的变长模板技术解决了“L数目”q部分,我们在这里把 N 看做L数目Q。乍看之下很奇Q实际上很简单:</p> <p> </p> <p>C:\Temp>type perfect.cpp</p> <p>#include <iostream></p> <p>#include <ostream></p> <p>using namespace std;</p> <p> </p> <p>template <typename T> struct Identity {</p> <p>    typedef T type;</p> <p>};</p> <p> </p> <p>template <typename T> T&& Forward(typename Identity<T>::type&& t) {</p> <p>    return t;</p> <p>}</p> <p> </p> <p>void inner(int&, int&) {</p> <p>    cout << "inner(int&, int&)" << endl;</p> <p>}</p> <p> </p> <p>void inner(int&, const int&) {</p> <p>    cout << "inner(int&, const int&)" << endl;</p> <p>}</p> <p> </p> <p>void inner(const int&, int&) {</p> <p>    cout << "inner(const int&, int&)" << endl;</p> <p>}</p> <p> </p> <p>void inner(const int&, const int&) {</p> <p>    cout << "inner(const int&, const int&)" << endl;</p> <p>}</p> <p> </p> <p><strong>template <typename T1, typename T2> void outer(T1&& t1, T2&& t2) {</strong></p> <p><strong>    inner(Forward<T1>(t1), Forward<T2>(t2));</strong></p> <p><strong>}</strong></p> <p> </p> <p>int main() {</p> <p>    int a = 1;</p> <p>    const int b = 2;</p> <p> </p> <p>    cout << "Directly calling inner()." << endl;</p> <p> </p> <p>    inner(a, a);</p> <p>    inner(b, b);</p> <p>    inner(3, 3);</p> <p> </p> <p>    inner(a, b);</p> <p>    inner(b, a);</p> <p> </p> <p>    inner(a, 3);</p> <p>    inner(3, a);</p> <p> </p> <p>    inner(b, 3);</p> <p>    inner(3, b);</p> <p> </p> <p>    cout << endl << "Calling outer()." << endl;</p> <p> </p> <p>    outer(a, a);</p> <p>    outer(b, b);</p> <p>    outer(3, 3);</p> <p> </p> <p>    outer(a, b);</p> <p>    outer(b, a);</p> <p> </p> <p>    outer(a, 3);</p> <p>    outer(3, a);</p> <p> </p> <p>    outer(b, 3);</p> <p>    outer(3, b);</p> <p>}</p> <p> </p> <p>C:\Temp>cl /EHsc /nologo /W4 perfect.cpp</p> <p>perfect.cpp</p> <p> </p> <p>C:\Temp>perfect</p> <p>Directly calling inner().</p> <p>inner(int&, int&)</p> <p>inner(const int&, const int&)</p> <p>inner(const int&, const int&)</p> <p>inner(int&, const int&)</p> <p>inner(const int&, int&)</p> <p>inner(int&, const int&)</p> <p>inner(const int&, int&)</p> <p>inner(const int&, const int&)</p> <p>inner(const int&, const int&)</p> <p> </p> <p>Calling outer().</p> <p>inner(int&, int&)</p> <p>inner(const int&, const int&)</p> <p>inner(const int&, const int&)</p> <p>inner(int&, const int&)</p> <p>inner(const int&, int&)</p> <p>inner(int&, const int&)</p> <p>inner(const int&, int&)</p> <p>inner(const int&, const int&)</p> <p>inner(const int&, const int&)</p> <p> </p> <p>两行Q完{发只用了两行Q够z吧Q?/p> <p> </p> <p>q个例子C了怎么?t1 ?t2 ?outerQ) 透明地{发给 innerQ)Q?innerQ) 可以知道它们的非帔R/帔RQ?lvalue/ravlue 属性,像inner是被直接调用的那栗?/p> <p> </p> <p>?stdQ:move() 一P std::identify ?std::forward() 都是?C++<utility> 中定义的Q?VC10 会有Q?VC10 CTP中没有)。我演C怎么来实现它们。(再次Q我交替?std::identity 和我?IdentityQ?std::forward() 和我?Forward()Q因Z们的实现是等L(fng)。)</p> <p> </p> <p>现在Q让我们来揭开“术“的神U面U,其实它靠的就是模板参数推导和引用折叠(reference collapsing)技术?/p> <p><strong> </strong></p> <p><strong>rvalue </strong><strong>引用Q模板参数推</strong><strong>?/strong><strong>和引用折?reference collapsing)</strong><strong></strong></p> <p> </p> <p>rvalue 引用与模板以一U特别的方式怺作用。下面是一个示例:</p> <p> </p> <p>C:\Temp>type collapse.cpp</p> <p>#include <iostream></p> <p>#include <ostream></p> <p>#include <string></p> <p>using namespace std;</p> <p> </p> <p>template <typename T> struct Name;</p> <p> </p> <p>template <> struct Name<string> {</p> <p>    static const char * get() {</p> <p>        return "string";</p> <p>    }</p> <p>};</p> <p> </p> <p>template <> struct Name<const string> {</p> <p>    static const char * get() {</p> <p>        return "const string";</p> <p>    }</p> <p>};</p> <p> </p> <p>template <> struct Name<string&> {</p> <p>    static const char * get() {</p> <p>        return "string&";</p> <p>    }</p> <p>};</p> <p> </p> <p>template <> struct Name<const string&> {</p> <p>    static const char * get() {</p> <p>        return "const string&";</p> <p>    }</p> <p>};</p> <p> </p> <p>template <> struct Name<string&&> {</p> <p>    static const char * get() {</p> <p>        return "string&&";</p> <p>    }</p> <p>};</p> <p> </p> <p>template <> struct Name<const string&&> {</p> <p>    static const char * get() {</p> <p>        return "const string&&";</p> <p>    }</p> <p>};</p> <p> </p> <p>template <typename T> void quark(T&& t) {</p> <p>    cout << "t: " << t << endl;</p> <p>    cout << "T: " << Name<T>::get() << endl;</p> <p>    cout << "T&&: " << Name<T&&>::get() << endl;</p> <p>    cout << endl;</p> <p>}</p> <p> </p> <p>string strange() {</p> <p>    return "strange()";</p> <p>}</p> <p> </p> <p>const string charm() {</p> <p>    return "charm()";</p> <p>}</p> <p> </p> <p>int main() {</p> <p>    string up("up");</p> <p>    const string down("down");</p> <p> </p> <p>    quark(up);</p> <p>    quark(down);</p> <p>    quark(strange());</p> <p>    quark(charm());</p> <p>}</p> <p> </p> <p>C:\Temp>cl /EHsc /nologo /W4 collapse.cpp</p> <p>collapse.cpp</p> <p> </p> <p>C:\Temp>collapse</p> <p>t: up</p> <p>T: string&</p> <p>T&&: string&</p> <p> </p> <p>t: down</p> <p>T: const string&</p> <p>T&&: const string&</p> <p> </p> <p>t: strange()</p> <p>T: string</p> <p>T&&: string&&</p> <p> </p> <p>t: charm()</p> <p>T: const string</p> <p>T&&: const string&&</p> <p> </p> <p>q里藉由 Name 的显式规D明来打印出类型?/p> <p> </p> <p>当我们调?quark(up) Ӟ会进行模板参数推对{?quark() 是一个带有模板参?T 的模板函敎ͼ但是我们q没有ؓ它提供显式的cd参数Q比如像 quark<X>(up)q样的)。通过比较函数形参cd Type&& 和函数实参类型(一?string cd?lvalueQ我们就能推导出模板实参cd。(译注Q原文用 argument 表示实参Qparameter 表示形参Q?/p> <p> </p> <p>C++0x 会{换函数实参的cd和Ş参的cdQ然后再q行匚w?/p> <p> </p> <p>首先Q{换函数实参的cd。这遵@一?strong>Ҏ(gu)</strong><strong>规则</strong>(提案N2798 </p> <p> </p> <p>然后Q{换函数Ş参的cd。不是 C++98/03 q是 C++0x 都会解除引用( lvalue 引用?rvalue 引用?C++0x 中都会被解除?。在前面例子的四U情形中Q这h们会?<strong>T&&</strong> 转换?<strong>T</strong> ?/p> <p> </p> <p>于是Q?<strong>T</strong> <strong>会被?/strong><strong>?/strong><strong>成函?/strong><strong>?/strong><strong>?/strong><strong>转换</strong><strong>之后?/strong><strong>c?/strong><strong>?/strong>?strong>up</strong> ?<strong>down</strong> 都是 lvalueQ它们遵循那条特D规则,q就是ؓ什?<strong>quark(up)  </strong>打印?<strong>T:string&</strong>" Q?<strong>quark(down)</strong> 打印?"<strong>T: cosnt string&</strong>"的原因?strong>strange()</strong> ?<strong>charm()</strong> 都是叛_|它们遵@一般规则,q就是ؓ什?<strong>quark(strange())</strong> 打印?"<strong>T: string</strong>" ?<strong>quark(charm())</strong> 打印?<strong>T: const string</strong>" 的原因?/p> <p> </p> <p>替换操作会在cd推导之后q行。模板Ş?<strong>T</strong> 出现的每一个地斚w会被替换成推导出来的模板实参cd。在 <strong>quark(string())</strong> ?<strong>T</strong> ?<strong>string </strong>Q因?<strong>T&&</strong> 会是 <strong>string&&</strong> 。同P?<strong>quark(charm())</strong> 中,<strong>T</strong> ?<strong>const string</strong> Q?因此 <strong>T&&</strong> ?<strong>const string&&</strong> 。但 quark(up) ?quark(down) 不同Q它们遵循另外的Ҏ(gu)规则?/p> <p> </p> <p>?<strong>quark(up)</strong> 中, <strong>T</strong> ?<strong>string&</strong> 。进行替换的?<strong>T&&</strong> 成?<strong>string& &&</strong> Q在 C++0x 中会折叠QcollapseQ引用的引用Q?strong>引用折叠?/strong><strong>规则</strong><strong>是</strong><strong>“lvalue </strong><strong>引用?/strong><strong>?/strong><strong>染性的</strong><strong>”</strong>?<strong>X& &</strong>, <strong>X& &&</strong> ?<strong>X&& &</strong> 都会被折叠成 <strong>X&</strong> Q只?<strong>X&& &&</strong> 会被折叠?<strong>X&&</strong> 。因?<strong>string& &&</strong> 被折叠成 <strong>string&</strong> 。在模板世界里,那些看v来像 rvalue 引用的东西ƈ不一定真的就是?因?<strong>quark(up)</strong> 被实例化?<strong>quark<string&>()</strong> Q进?<strong>T&&</strong> l替换与折叠之后变成 <strong>string&</strong> 。我们可以调?<strong>Name<T&&>::get()</strong> 来验证这个?同样Q?<strong>quark(down)</strong> 被实例化?<strong>quark<const string&>()</strong> Q进?<strong>T&&</strong> l替换与折叠之后变成 <strong>const string&</strong> 。在 C++98/03中,你可能习惯了帔R?constness)隐藏于模板Ş参中(也就是说可以?<strong>const Foo</strong> 对象作实参来调用形参?<strong>T&</strong> 的模板函敎ͼ像 <strong>T&</strong> 会是 <strong>const Foo&</strong> 一?Q在 C++0x 中,左值属?lvalueness) 也能隐藏于模板Ş参中?/p> <p> </p> <p>那好Q这两条Ҏ(gu)规则Ҏ(gu)们有什么媄响??quark() 内部Q类?<strong>T&&</strong> 有着和传l?<strong>quark() </strong>的实参一L(fng)?叛_属?lvalueness/rvalueness)和常量性。这?<strong>rvalue 引用p保持住左?/strong><strong>?/strong><strong>属性和帔R性,做到完美</strong><strong>转发</strong><strong>?/strong></p> <p><strong> </strong></p> <p><strong>完美</strong><strong>转发</strong><strong>Q?std::forward() ?std::identidy 是?/strong><strong>?/strong><strong>工作?/strong></p> <p> </p> <p>让我们再来看?outer() :</p> <p> </p> <p><strong>template <typename T1, typename T2> void outer(T1&& t1, T2&& t2) {</strong></p> <p><strong>    inner(Forward<T1>(t1), Forward<T2>(t2));</strong></p> <p><strong>}</strong></p> <p> </p> <p>现在我们明白了ؓ什?strong> outer()</strong> 的Ş参是 <strong>T1&&</strong> ?<strong>T2&&</strong> cd的了Q因为它们能够保持住传给 <strong>outer()</strong> 的实参的信息。那Z么这里要调用 <strong>Forward<T1>()</strong> ?<strong>Forward<T2>()</strong> 呢?q记得么Q具?lvalue 引用和具?rvalue 引用都是 lvalue 。如?<strong>outer()</strong> 调用 <strong>inner(t1, t2)</strong> Q那?<strong>inner()</strong> L会当 lvalue 来引?<strong>t1</strong> ?<strong>t2</strong> Q这q坏了完美转发?/p> <p> </p> <p>q?q的是,不具?lvalue 引用?lvalueQ不具名 rvalue 引用q是 rvalue 。因此,Z?t1 ?t2 转发l?inner()Q我们需要将它们传到一个帮助函C去,q个帮助函数U除它们的名字,保持住它们的属性信息。这是 std::forward() 做的事情Q?/p> <p> </p> <p><strong>template <typename T> struct Identity {</strong></p> <p><strong>    typedef T type;</strong></p> <p><strong>};</strong></p> <p><strong> </strong></p> <p><strong>template <typename T> T&& Forward(typename Identity<T>::type&& t) {</strong></p> <p><strong>    return t;</strong></p> <p><strong>}</strong></p> <p> </p> <p>当我们调?<strong>Forward<T1>(t1)</strong> Q?<strong>Identidy</strong> q没有修?<strong>T1</strong> Q很快我们讲?<strong>Identidy</strong> ?<strong>T1</strong> 做了什么)。因?<strong>Forward<T1>()</strong> 接收 <strong>T1&&</strong> Q返?<strong>T1&&</strong> 。这样就U除?<strong>t1</strong> 的名字,保持?<strong>t1</strong> 的类型信息(而不?<strong>t1</strong> 是什么类型, string& 也好, const string& 也好, string&& 也好?const string&& 也好Q。这?<strong>inner()</strong> 看到?<strong>Forward<T1>(t1)</strong> Q与 <strong>outer()</strong> 接收的第一个实参有着相同的信息,包括cdQlvalueness/rvaluenessQ常量性等{。完{发就是这样工作的?/p> <p> </p> <p>你可能会好奇如果不小心写?<strong>Forward<T1&&>(t1) </strong>又会怎样呢?Q这个错误还是蛮׃h的,因ؓ <strong>outer() </strong>接收的就?<strong>T1&& t1</strong> Q。很q运Q没什么坏事情会发生?<strong>Forward<T1&&>()</strong> 接收与返回的都是 <strong>T1&& &&</strong> Q这会被折叠?<strong>T1&&</strong> 。于是,<strong>Forward<T1>(t1)</strong> ?<strong>Forward<T1&&>(t1)</strong> 是等L(fng)Q我们更偏好前者,是因为它要短些?/p> <p> </p> <p><strong>Identidy</strong> 是做什么用的呢Qؓ什么下面的代码不能工作Q?/p> <p> </p> <p><strong>template <typename T> T&& Forward(T&& t) { // BROKEN</strong></p> <p><strong>    return t;</strong></p> <p><strong>}</strong></p> <p> </p> <p>如果 <strong>Forward()</strong> 像是上面那样Q它?yu)p被隐式调用(不带明确的模板参敎ͼ。当我们传给<strong> Forward()</strong> 一?lvalue 实参Ӟ模板参数推导׃入了Q如我们前面看到的那样会?<strong>T&&</strong> 变成 <strong>T&</strong>Q也是变成一?lvalue 引用。问题来了,即形参 <strong>T1&&</strong> ?<strong>T2&&</strong> 指明?rvalue 引用Q但?<strong>outer()</strong> 中,具名?<strong>t1</strong> ?<strong>t2</strong> 却是 lvaue Q这个问题是我们一直想要解决的Q用上面那个错误的实现Q?<strong>Forward<T1>(t1)</strong> 是可以工作的Q?<strong>Foarward(t1)</strong> 虽然能通过~译Q很׃h哦)但会出错Q就如它?yu)?<strong>t1</strong> 一栗真是痛苦的源泉啊,因此Q?strong>Identity</strong> <strong>被用来阻止模板参数推</strong><strong>?/strong>?strong>typename Identity<T>::type</strong> 中的那对冒号像l缘体,模板参数推导无法I越它,有模板编E经验的E序员应该对此很熟?zhn)了,因ؓq在 C++98/03 ?C++0x 中是一L(fng)。(要解释这个是另外的事情了Q?/p> <p> </p> <p><strong>move </strong><strong>?/strong><strong>意:</strong><strong> std::move() </strong><strong>是?/strong><strong>?/strong><strong>工作?/strong></p> <p> </p> <p>现在我们已经学习了模板参数推导和引用折叠的特D规则,让我们再来看?std::move() :</p> <p> </p> <p><strong>template <typename T> struct RemoveReference {</strong></p> <p><strong>     typedef T type;</strong></p> <p><strong>};</strong></p> <p><strong> </strong></p> <p><strong>template <typename T> struct RemoveReference<T&> {</strong></p> <p><strong>     typedef T type;</strong></p> <p><strong>};</strong></p> <p><strong> </strong></p> <p><strong>template <typename T> struct RemoveReference<T&&> {</strong></p> <p><strong>     typedef T type;</strong></p> <p><strong>};</strong></p> <p><strong> </strong></p> <p><strong>template <typename T> typename RemoveReference<T>::type&& Move(T&& t) {</strong></p> <p><strong>    return t;</strong></p> <p><strong>}</strong></p> <p><strong> </strong></p> <p><strong>RemoveReference </strong>机制基本上是复制 C++0x <type_traits> 中的 <strong>std::remove_reference</strong> 。D例来_<strong>RemoveReference<string>::type</strong> , <strong>RemoveReference<string&>::type</strong> ?<strong>RemoveReference<string&&>::type</strong> 都是 <strong>string </strong>?/p> <p> </p> <p>同样Q?<strong>move()</strong> 机制也基本上是复?C++0x <utility> 中的 <strong>std::move()</strong>?</p> <p>· 当调?<strong>Move(string)</strong>, <strong>string </strong>是一?lvalue Ӟ <strong>T</strong> 会被推导?<strong>string&</strong> Q于?strong> Move()</strong> 接收的就?<strong>string&</strong> (l折叠之?q返?<strong>string&&</strong> (l?<strong>RemoveReference </strong>之后)?/p> <p> </p> <p>· 当调?<strong>Move(const string)</strong>, <strong>const</strong> <strong>string </strong>是一?lvalue Ӟ <strong>T</strong> 会被推导?<strong>const string&</strong> Q于?<strong>Move()</strong> 接收的就?<strong>const string&&</strong> (l折叠之?q返?<strong>const string&&</strong> (l?<strong>RemoveReference </strong>之后)?/p> <p> </p> <p>· 当调?<strong>Move(string)</strong>, <strong>string </strong>是一?rvalue Ӟ <strong>T</strong> 会被推导?<strong>string</strong> Q于?strong> Move()</strong> 接收的就?<strong>string&&</strong> q返?<strong>string&&</strong> ?/p> <p> </p> <p>· 当调?<strong>Move(const string)</strong>, <strong>const</strong> <strong>string </strong>是一?rvalue Ӟ <strong>T</strong> 会被推导?<strong>const string</strong> Q于?<strong>Move()</strong> 接收的就?<strong>const string&&</strong> q返?<strong>const string&&</strong> ?/p> <p> </p> <p>q就?Move() 如何保持其参数的cd和常量性,q能?lvalue 转换?rvalue 的过E?/p> <p> </p> <p><strong>?/strong><strong>?/strong><strong></strong></p> <p>如果你想?rvalue 引用有更多了 解,你可以去L兛_们的提案。要注意Q提案与现在的决定可能已l不同了Q?rvalue 引用已经被整合到 C++0x 草案中来了,在那里它得到持箋的改q。有些提案或已不再正,或已q时Q或已有了替代方案,没有被采纳。无论怎样Q它们还是能提供一些有用信息的?/p> <p> </p> <p><a >N1377</a>, <a >N1385</a>, ?<a >N1690</a> 是主要的提案Q?a >N2118</a> 包含被整合进标准草案之前的最后版本?<a >N1784</a>, <a >N1821</a>, <a >N2377</a>, ?<a >N2439</a> 记录?#8220;?Move 语意扩展?*this ”的演化过E,q个也被整合?C++0x 中来了,但还没有在VC10 中得到实现?/p> <p> </p> <p><strong>展望</strong></p> <p><a >N2812</a> “Rvalue 引用的安全问题(以及如何解决Q?#8221; 提出了对初始化规则的修改Q它止 rvalue 引用l定?lvalue ?q不会媄?move 语意和完{发,所以它不会让你刚学到的新技术失效(它只是修改了 std::move() ?std::forward() 的实玎ͼ?/p> <p> </p> <p>Stephan T. Lavavej</p> <p>Visual C++ Libraries Developer</p> <p>Published Tuesday, February 03, 2009 9:27 AM by <a >vcblog</a></p> <p>译Q?a href="http://www.shnenglu.com/kesalin/">飘飘白云</a></p> <p> </p> <p style="TEXT-ALIGN: center">(转蝲时请注明作者和出处。未l许可,请勿用于商业用?</p> <p style="TEXT-ALIGN: center"> < <a href="http://www.shnenglu.com/kesalin/archive/2009/06/01/86461.html">W一?/a>Q?<a href="http://www.shnenglu.com/kesalin/archive/2009/06/04/86720.html">W二?/a>Q?本页></p> <br> <p> </p> <br><br> <img src ="http://www.shnenglu.com/kesalin/aggbug/86851.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/kesalin/" target="_blank">|朝?/a> 2009-06-05 15:09 <a href="http://www.shnenglu.com/kesalin/archive/2009/06/05/86851.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>【译】VC10中的C++0xҎ(gu)?part 2Q?Q?叛_引?/title><link>http://www.shnenglu.com/kesalin/archive/2009/06/04/86720.html</link><dc:creator>|朝?/dc:creator><author>|朝?/author><pubDate>Thu, 04 Jun 2009 01:37:00 GMT</pubDate><guid>http://www.shnenglu.com/kesalin/archive/2009/06/04/86720.html</guid><wfw:comment>http://www.shnenglu.com/kesalin/comments/86720.html</wfw:comment><comments>http://www.shnenglu.com/kesalin/archive/2009/06/04/86720.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.shnenglu.com/kesalin/comments/commentRss/86720.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/kesalin/services/trackbacks/86720.html</trackback:ping><description><![CDATA[<p style="TEXT-ALIGN: center"> <h3 style="FONT-FAMILY: 宋体; TEXT-ALIGN: center">【译】VC10中的C++0xҎ(gu)?part 2Q?Q?叛_引?/h3> 来源Q?a title=vcvlog target=_blank>vcblog</a> 作者:Stephan T. Lavavej 译Q?a title=飘飘白云的C++博客 href="http://www.shnenglu.com/kesalin" target=_blank>飘飘白云</a>   <p> </p> <p style="FONT-SIZE: 12pt"></p> <p style="TEXT-ALIGN: center">(转蝲时请注明作者和出处。未l许可,请勿用于商业用? <br></p> <p>?</p> <div id="6616611" class=postText><style> <!-- /* Font Definitions */ @font-face {font-family:Wingdings; panose-1:5 0 0 0 0 0 0 0 0 0; mso-font-charset:2; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:0 268435456 0 0 -2147483648 0;} @font-face {font-family:"MS Mincho"; panose-1:2 2 6 9 4 2 5 8 3 4; mso-font-alt:"QS 明朝"; mso-font-charset:128; mso-generic-font-family:modern; mso-font-pitch:fixed; mso-font-signature:-1610612033 1757936891 16 0 131231 0;} @font-face {font-family:宋体; panose-1:2 1 6 0 3 1 1 1 1 1; mso-font-alt:SimSun; mso-font-charset:134; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:3 135135232 16 0 262145 0;} @font-face {font-family:Century; panose-1:2 4 6 4 5 5 5 2 3 4; mso-font-charset:0; mso-generic-font-family:roman; mso-font-pitch:variable; mso-font-signature:647 0 0 0 159 0;} @font-face {font-family:"MS PGothic"; panose-1:2 11 6 0 7 2 5 8 2 4; mso-font-charset:128; mso-generic-font-family:swiss; mso-font-pitch:variable; mso-font-signature:-1610612033 1757936891 16 0 131231 0;} @font-face {font-family:Verdana; panose-1:2 11 6 4 3 5 4 4 2 4; mso-font-charset:0; mso-generic-font-family:swiss; mso-font-pitch:variable; mso-font-signature:536871559 0 0 0 415 0;} @font-face {font-family:"\@MS PGothic"; panose-1:2 11 6 0 7 2 5 8 2 4; mso-font-charset:128; mso-generic-font-family:swiss; mso-font-pitch:variable; mso-font-signature:-1610612033 1757936891 16 0 131231 0;} @font-face {font-family:"\@宋体"; panose-1:2 1 6 0 3 1 1 1 1 1; mso-font-charset:134; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:3 135135232 16 0 262145 0;} @font-face {font-family:"\@MS Mincho"; panose-1:2 2 6 9 4 2 5 8 3 4; mso-font-charset:128; mso-generic-font-family:modern; mso-font-pitch:fixed; mso-font-signature:-1610612033 1757936891 16 0 131231 0;} /* Style Definitions */ p.MsoNormal, li.MsoNormal, div.MsoNormal {mso-style-parent:""; margin:0cm; margin-bottom:.0001pt; text-align:justify; text-justify:inter-ideograph; mso-pagination:none; font-size:10.5pt; mso-bidi-font-size:12.0pt; font-family:Century; mso-fareast-font-family:"MS Mincho"; mso-bidi-font-family:"Times New Roman"; mso-font-kerning:1.0pt; mso-fareast-language:JA;} h1 {mso-margin-top-alt:auto; margin-right:0cm; mso-margin-bottom-alt:auto; margin-left:0cm; mso-pagination:widow-orphan; mso-outline-level:1; font-size:24.0pt; font-family:"MS PGothic"; mso-bidi-font-family:"MS PGothic"; mso-fareast-language:JA;} p.MsoHeader, li.MsoHeader, div.MsoHeader {margin:0cm; margin-bottom:.0001pt; text-align:justify; text-justify:inter-ideograph; mso-pagination:none; tab-stops:center 212.6pt right 425.2pt; layout-grid-mode:char; font-size:10.5pt; mso-bidi-font-size:12.0pt; font-family:Century; mso-fareast-font-family:"MS Mincho"; mso-bidi-font-family:"Times New Roman"; mso-font-kerning:1.0pt; mso-fareast-language:JA;} p.MsoFooter, li.MsoFooter, div.MsoFooter {margin:0cm; margin-bottom:.0001pt; text-align:justify; text-justify:inter-ideograph; mso-pagination:none; tab-stops:center 212.6pt right 425.2pt; layout-grid-mode:char; font-size:10.5pt; mso-bidi-font-size:12.0pt; font-family:Century; mso-fareast-font-family:"MS Mincho"; mso-bidi-font-family:"Times New Roman"; mso-font-kerning:1.0pt; mso-fareast-language:JA;} a:link, span.MsoHyperlink {color:blue; text-decoration:underline; text-underline:single;} a:visited, span.MsoHyperlinkFollowed {color:purple; text-decoration:underline; text-underline:single;} /* Page Definitions */ @page {mso-page-border-surround-header:no; mso-page-border-surround-footer:no;} @page Section1 {size:595.3pt 841.9pt; margin:99.25pt 3.0cm 3.0cm 3.0cm; mso-header-margin:42.55pt; mso-footer-margin:49.6pt; mso-paper-source:0; layout-grid:18.0pt;} div.Section1 {page:Section1;} --> </style> <p>q一pd文章介绍Microsoft Visual Studio 2010 中支持的C++ 0xҎ(gu),目前有三部分?<br><a title="VC10中的C++0xҎ(gu)?part 1" target=_blank>Part 1</a> Q介l了LambdasQ?赋予新意义的autoQ以?static_assertQ?<br>Part 2( <a title="VC10中的C++0xҎ(gu)?part 2 W一部分" href="http://www.shnenglu.com/kesalin/archive/2009/05/28/85983.html" target=_blank>一</a> , <a title="VC10中的C++0xҎ(gu)?part 2 W二部分" href="http://www.shnenglu.com/kesalin/archive/2009/06/04/86720.html" target=_blank>?/a> , <a title="VC10中的C++0xҎ(gu)?part 2 W三部分 " href="http://www.shnenglu.com/kesalin/archive/2009/06/05/86851.html" target=_blank>?/a> )Q介l了叛_引用(Rvalue ReferencesQ; <br><a title="VC10中的C++0xҎ(gu)?part 3" href="http://www.shnenglu.com/kesalin/archive/2009/06/07/86960.html" target=_blank>Part 3</a>Q介l了表达式类型(decltypeQ?br><br>VC10中的C++0xҎ(gu)?Part 1,2,3 译文打包下蝲Qdoc ?pdf 格式Q: <a title="VC10中的C++0xҎ(gu)(Part 1,2,3Q译文doc和pdf文档" href="http://www.shnenglu.com/Files/kesalin/Cplusplus0x_in_VC10.zip" target=_blank>Ҏ(gu)下蝲</a></p> </div> <br> <object id=ieooui classid=clsid:38481807-ca0e-42d2-bf39-b33af135cc4d></object><style> st1\:*{behavior:url(#ieooui) } </style>本文?Part 2 W二c? <p style="FONT-FAMILY: 宋体"></p> <br style="FONT-FAMILY: 宋体"> <meta content=Word.Document name=ProgId> <meta content="Microsoft Word 11" name=Generator> <meta content="Microsoft Word 11" name=Originator> <link style="FONT-FAMILY: 宋体" href="file:///C:%5CDOCUME%7E1%5CLUO%7E1.ZHA%5CLOCALS%7E1%5CTemp%5Cmsohtml1%5C02%5Cclip_filelist.xml" rel=File-List><style> <!-- /* Font Definitions */ @font-face {font-family:"QS 明朝"; panose-1:2 2 6 9 4 2 5 8 3 4; mso-font-alt:"MS Mincho"; mso-font-charset:128; mso-generic-font-family:roman; mso-font-pitch:fixed; mso-font-signature:-1610612033 1757936891 16 0 131231 0;} @font-face {font-family:SimSun; panose-1:2 1 6 0 3 1 1 1 1 1; mso-font-alt:宋体; mso-font-charset:134; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:3 135135232 16 0 262145 0;} @font-face {font-family:Century; panose-1:2 4 6 4 5 5 5 2 3 4; mso-font-charset:0; mso-generic-font-family:roman; mso-font-pitch:variable; mso-font-signature:647 0 0 0 159 0;} @font-face {font-family:"QS Qゴ゗?; panose-1:2 11 6 0 7 2 5 8 2 4; mso-font-charset:128; mso-generic-font-family:modern; mso-font-pitch:variable; mso-font-signature:-1610612033 1757936891 16 0 131231 0;} @font-face {font-family:"\@SimSun"; panose-1:2 1 6 0 3 1 1 1 1 1; mso-font-charset:134; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:3 135135232 16 0 262145 0;} @font-face {font-family:"\@QS Qゴ゗?; panose-1:2 11 6 0 7 2 5 8 2 4; mso-font-charset:128; mso-generic-font-family:modern; mso-font-pitch:variable; mso-font-signature:-1610612033 1757936891 16 0 131231 0;} @font-face {font-family:"\@QS 明朝"; panose-1:2 2 6 9 4 2 5 8 3 4; mso-font-charset:128; mso-generic-font-family:roman; mso-font-pitch:fixed; mso-font-signature:-1610612033 1757936891 16 0 131231 0;} /* Style Definitions */ p.MsoNormal, li.MsoNormal, div.MsoNormal {mso-style-parent:""; margin:0mm; margin-bottom:.0001pt; text-align:justify; text-justify:inter-ideograph; mso-pagination:none; font-size:10.5pt; mso-bidi-font-size:12.0pt; font-family:Century; mso-fareast-font-family:"QS 明朝"; mso-bidi-font-family:"Times New Roman"; mso-font-kerning:1.0pt;} /* Page Definitions */ @page {mso-page-border-surround-header:no; mso-page-border-surround-footer:no;} @page Section1 {size:612.0pt 792.0pt; margin:99.25pt 30.0mm 30.0mm 30.0mm; mso-header-margin:36.0pt; mso-footer-margin:36.0pt; mso-paper-source:0;} div.Section1 {page:Section1;} --> </style> <p style="FONT-FAMILY: 宋体"><strong>move </strong><strong>语意Q从</strong><strong> lvalue </strong><strong>Ud</strong></p> <p style="FONT-FAMILY: 宋体"><br></p> <p style="FONT-FAMILY: 宋体">现在Q如果你喜欢用拷贝赋值函数来实现你的拯构造函数该怎样做呢Q那你也可能试图?move 拯赋值函数来实现 move 构造函数。这样作是可以的Q但是你得小心。下面就是一个错误的实现Q?/p> <p style="FONT-FAMILY: 宋体"> </p> <p style="FONT-FAMILY: courier new">C:\Temp>type unified_wrong.cpp</p> <p style="FONT-FAMILY: courier new">#include <stddef.h></p> <p style="FONT-FAMILY: courier new">#include <iostream></p> <p style="FONT-FAMILY: courier new">#include <ostream></p> <p style="FONT-FAMILY: courier new">using namespace std;</p> <p style="FONT-FAMILY: courier new"> </p> <p style="FONT-FAMILY: courier new">class remote_integer {</p> <p style="FONT-FAMILY: courier new">public:</p> <p style="FONT-FAMILY: courier new">    remote_integer() {</p> <p style="FONT-FAMILY: courier new">        cout << "Default constructor." << endl;</p> <p style="FONT-FAMILY: courier new"> </p> <p style="FONT-FAMILY: courier new">        m_p = NULL;</p> <p style="FONT-FAMILY: courier new">    }</p> <p style="FONT-FAMILY: courier new"> </p> <p style="FONT-FAMILY: courier new">    explicit remote_integer(const int n) {</p> <p style="FONT-FAMILY: courier new">        cout << "Unary constructor." << endl;</p> <p style="FONT-FAMILY: courier new"> </p> <p style="FONT-FAMILY: courier new">        m_p = new int(n);</p> <p style="FONT-FAMILY: courier new">    }</p> <p style="FONT-FAMILY: courier new"> </p> <p style="FONT-FAMILY: courier new">    remote_integer(const remote_integer& other) {</p> <p style="FONT-FAMILY: courier new">        cout << "Copy constructor." << endl;</p> <p style="FONT-FAMILY: courier new"> </p> <p style="FONT-FAMILY: courier new">        m_p = NULL;</p> <p style="FONT-FAMILY: courier new">        *this = other;</p> <p style="FONT-FAMILY: courier new">    }</p> <p style="FONT-FAMILY: courier new"> </p> <p style="FONT-FAMILY: courier new">#ifdef MOVABLE</p> <p style="FONT-FAMILY: courier new">    remote_integer(remote_integer&& other) {</p> <p style="FONT-FAMILY: courier new">        cout << "MOVE CONSTRUCTOR." << endl;</p> <p style="FONT-FAMILY: courier new"> </p> <p style="FONT-FAMILY: courier new">        m_p = NULL;</p> <p style="FONT-FAMILY: courier new">        *this = other; // WRONG</p> <p style="FONT-FAMILY: courier new">    }</p> <p style="FONT-FAMILY: courier new">#endif // #ifdef MOVABLE</p> <p style="FONT-FAMILY: courier new"> </p> <p style="FONT-FAMILY: courier new">    remote_integer& operator=(const remote_integer& other) {</p> <p style="FONT-FAMILY: courier new">        cout << "Copy assignment operator." << endl;</p> <p style="FONT-FAMILY: courier new"> </p> <p style="FONT-FAMILY: courier new">        if (this != &other) {</p> <p style="FONT-FAMILY: courier new">            delete m_p;</p> <p style="FONT-FAMILY: courier new"> </p> <p style="FONT-FAMILY: courier new">            if (other.m_p) {</p> <p style="FONT-FAMILY: courier new">                m_p = new int(*other.m_p);</p> <p style="FONT-FAMILY: courier new">            } else {</p> <p style="FONT-FAMILY: courier new">                m_p = NULL;</p> <p style="FONT-FAMILY: courier new">            }</p> <p style="FONT-FAMILY: courier new">        }</p> <p style="FONT-FAMILY: courier new"> </p> <p style="FONT-FAMILY: courier new">        return *this;</p> <p style="FONT-FAMILY: courier new">    }</p> <p style="FONT-FAMILY: courier new"> </p> <p style="FONT-FAMILY: courier new">#ifdef MOVABLE</p> <p style="FONT-FAMILY: courier new">    remote_integer& operator=(remote_integer&& other) {</p> <p style="FONT-FAMILY: courier new">        cout << "MOVE ASSIGNMENT OPERATOR." << endl;</p> <p style="FONT-FAMILY: courier new"> </p> <p style="FONT-FAMILY: courier new">        if (this != &other) {</p> <p style="FONT-FAMILY: courier new">            delete m_p;</p> <p style="FONT-FAMILY: courier new"> </p> <p style="FONT-FAMILY: courier new">            m_p = other.m_p;</p> <p style="FONT-FAMILY: courier new">            other.m_p = NULL;</p> <p style="FONT-FAMILY: courier new">        }</p> <p style="FONT-FAMILY: courier new"> </p> <p style="FONT-FAMILY: courier new">        return *this;</p> <p style="FONT-FAMILY: courier new">    }</p> <p style="FONT-FAMILY: courier new">#endif // #ifdef MOVABLE</p> <p style="FONT-FAMILY: courier new"> </p> <p style="FONT-FAMILY: courier new">    ~remote_integer() {</p> <p style="FONT-FAMILY: courier new">        cout << "Destructor." << endl;</p> <p style="FONT-FAMILY: courier new"> </p> <p style="FONT-FAMILY: courier new">        delete m_p;</p> <p style="FONT-FAMILY: courier new">    }</p> <p style="FONT-FAMILY: courier new"> </p> <p style="FONT-FAMILY: courier new">    int get() const {</p> <p style="FONT-FAMILY: courier new">        return m_p ? *m_p : 0;</p> <p style="FONT-FAMILY: courier new">    }</p> <p style="FONT-FAMILY: courier new"> </p> <p style="FONT-FAMILY: courier new">private:</p> <p style="FONT-FAMILY: courier new">    int * m_p;</p> <p style="FONT-FAMILY: courier new">};</p> <p style="FONT-FAMILY: courier new"> </p> <p style="FONT-FAMILY: courier new">remote_integer frumple(const int n) {</p> <p style="FONT-FAMILY: courier new">    if (n == 1729) {</p> <p style="FONT-FAMILY: courier new">        return remote_integer(1729);</p> <p style="FONT-FAMILY: courier new">    }</p> <p style="FONT-FAMILY: courier new"> </p> <p style="FONT-FAMILY: courier new">    remote_integer ret(n * n);</p> <p style="FONT-FAMILY: courier new"> </p> <p style="FONT-FAMILY: courier new">    return ret;</p> <p style="FONT-FAMILY: courier new">}</p> <p style="FONT-FAMILY: courier new"> </p> <p style="FONT-FAMILY: courier new">int main() {</p> <p style="FONT-FAMILY: courier new">    remote_integer x = frumple(5);</p> <p style="FONT-FAMILY: courier new"> </p> <p style="FONT-FAMILY: courier new">    cout << x.get() << endl;</p> <p style="FONT-FAMILY: courier new"> </p> <p style="FONT-FAMILY: courier new">    remote_integer y = frumple(1729);</p> <p style="FONT-FAMILY: courier new"> </p> <p style="FONT-FAMILY: courier new">    cout << y.get() << endl;</p> <p style="FONT-FAMILY: courier new">}</p> <p style="FONT-FAMILY: courier new"> </p> <p style="FONT-FAMILY: courier new">C:\Temp>cl /EHsc /nologo /W4 /O2 unified_wrong.cpp</p> <p style="FONT-FAMILY: courier new">unified_wrong.cpp</p> <p style="FONT-FAMILY: courier new"> </p> <p style="FONT-FAMILY: courier new">C:\Temp>unified_wrong</p> <p style="FONT-FAMILY: courier new">Unary constructor.</p> <p style="FONT-FAMILY: courier new">Copy constructor.</p> <p style="FONT-FAMILY: courier new">Copy assignment operator.</p> <p style="FONT-FAMILY: courier new">Destructor.</p> <p style="FONT-FAMILY: courier new">25</p> <p style="FONT-FAMILY: courier new">Unary constructor.</p> <p style="FONT-FAMILY: courier new">1729</p> <p style="FONT-FAMILY: courier new">Destructor.</p> <p style="FONT-FAMILY: courier new">Destructor.</p> <p style="FONT-FAMILY: courier new"> </p> <p style="FONT-FAMILY: courier new">C:\Temp>cl /EHsc /nologo /W4 /O2 /DMOVABLE unified_wrong.cpp</p> <p style="FONT-FAMILY: courier new">unified_wrong.cpp</p> <p style="FONT-FAMILY: courier new"> </p> <p style="FONT-FAMILY: courier new">C:\Temp>unified_wrong</p> <p style="FONT-FAMILY: courier new">Unary constructor.</p> <p style="FONT-FAMILY: courier new">MOVE CONSTRUCTOR.</p> <p style="FONT-FAMILY: courier new">Copy assignment operator.</p> <p style="FONT-FAMILY: courier new">Destructor.</p> <p style="FONT-FAMILY: courier new">25</p> <p style="FONT-FAMILY: courier new">Unary constructor.</p> <p style="FONT-FAMILY: courier new">1729</p> <p style="FONT-FAMILY: courier new">Destructor.</p> <p style="FONT-FAMILY: courier new">Destructor.</p> <p style="FONT-FAMILY: courier new"> </p> <p style="FONT-FAMILY: 宋体">(~译器在q里q行了返回g?RVO)Q但不是具名q回g?NRVO)。就像我之前提到的,有些拯构造函数被 RVO ?NRVO 优化掉了Q但~译器ƈ不L能够做这L(fng)优化Q这时剩余的q move 构造函数来优化?</p> <p style="FONT-FAMILY: 宋体"> </p> <p style="FONT-FAMILY: 宋体">move 构造函C标记?WRONG 的那一行,调用了拷贝赋值函敎ͼ~译能通过也能q行Q但q违背了 move 构造函数的本意。(译注Q因为那个拷贝赋值函数只是进行普通的拯赋|而不?move 赋|Q?/p> <p style="FONT-FAMILY: 宋体"> </p> <p style="FONT-FAMILY: 宋体">q是怎么回事呢?CQ在C++98/03中,具名 lvalue 引用是左?l定语句 int& r = *p; r ?lvalue)Q不具名 lvalue 引用q是左?l定语句 vector<int> v(10, 1729)Q?v[0] q回 int&Q?你可以对q个不具?lvalue 引用取址)。但?rvalue 引用׃一样了Q?/p> <p style="FONT-FAMILY: 宋体"> </p> <p style="FONT-FAMILY: 宋体"><strong>?/strong><strong> </strong><strong>具名</strong><strong> </strong><strong>lvalue</strong><strong> </strong><strong>引用?/strong><strong> </strong><strong>lvalue</strong><strong>?/strong><strong></strong></p> <p style="FONT-FAMILY: 宋体"><strong>?/strong><strong> </strong><strong>不具?/strong><strong> rvalue</strong><strong> </strong><strong>引用?/strong><strong> </strong><strong>rvalue</strong><strong>?/strong><strong></strong></p> <p style="FONT-FAMILY: 宋体"> </p> <p style="FONT-FAMILY: 宋体">一个具?rvalue 引用是一?lvalue 是因为可以对它施加多重操作,重复使用。相反,如果它是一?ravlue 的话Q那么对它施加的W一个操作能?#8220;H取”它,而后l操作就没机会了。这里的“H取”是说不会被察觉到Q所以这是行不通的。另一斚wQ不具名 rvalue 引用不能被重复用,所以它仍保持右?rvalueness)语意?/p> <p style="FONT-FAMILY: 宋体"> </p> <p style="FONT-FAMILY: 宋体">如果你真的打用 move 赋值函数来实现 move 构造函敎ͼ你需要从 lvalue moveQ就像是?rvalue move 一栗C++0x <utility> 中的 std::move() 具备q样的能力,VC10会有这个(实际上,开发版中已l有了)Q但VC10 TCP版还没有Q所以我会教你从头做P</p> <p style="FONT-FAMILY: 宋体"> </p> <p style="FONT-FAMILY: courier new">C:\Temp>type unified_right.cpp</p> <p style="FONT-FAMILY: courier new">#include <stddef.h></p> <p style="FONT-FAMILY: courier new">#include <iostream></p> <p style="FONT-FAMILY: courier new">#include <ostream></p> <p style="FONT-FAMILY: courier new">using namespace std;</p> <p style="FONT-FAMILY: courier new"> </p> <p style="FONT-FAMILY: courier new">template <typename T> struct RemoveReference {</p> <p style="FONT-FAMILY: courier new">     typedef T type;</p> <p style="FONT-FAMILY: courier new">};</p> <p style="FONT-FAMILY: courier new"> </p> <p style="FONT-FAMILY: courier new">template <typename T> struct RemoveReference<T&> {</p> <p style="FONT-FAMILY: courier new">     typedef T type;</p> <p style="FONT-FAMILY: courier new">};</p> <p style="FONT-FAMILY: courier new"> </p> <p style="FONT-FAMILY: courier new">template <typename T> struct RemoveReference<T&&> {</p> <p style="FONT-FAMILY: courier new">     typedef T type;</p> <p style="FONT-FAMILY: courier new">};</p> <p style="FONT-FAMILY: courier new"> </p> <p style="FONT-FAMILY: courier new">template <typename T> typename RemoveReference<T>::type&& Move(T&& t) {</p> <p style="FONT-FAMILY: courier new">    return t;</p> <p style="FONT-FAMILY: courier new">}</p> <p style="FONT-FAMILY: courier new"> </p> <p style="FONT-FAMILY: courier new">class remote_integer {</p> <p style="FONT-FAMILY: courier new">public:</p> <p style="FONT-FAMILY: courier new">    remote_integer() {</p> <p style="FONT-FAMILY: courier new">        cout << "Default constructor." << endl;</p> <p style="FONT-FAMILY: courier new"> </p> <p style="FONT-FAMILY: courier new">        m_p = NULL;</p> <p style="FONT-FAMILY: courier new">    }</p> <p style="FONT-FAMILY: courier new"> </p> <p style="FONT-FAMILY: courier new">    explicit remote_integer(const int n) {</p> <p style="FONT-FAMILY: courier new">        cout << "Unary constructor." << endl;</p> <p style="FONT-FAMILY: courier new"> </p> <p style="FONT-FAMILY: courier new">        m_p = new int(n);</p> <p style="FONT-FAMILY: courier new">    }</p> <p style="FONT-FAMILY: courier new"> </p> <p style="FONT-FAMILY: courier new">    remote_integer(const remote_integer& other) {</p> <p style="FONT-FAMILY: courier new">        cout << "Copy constructor." << endl;</p> <p style="FONT-FAMILY: courier new"> </p> <p style="FONT-FAMILY: courier new">        m_p = NULL;</p> <p style="FONT-FAMILY: courier new">        *this = other;</p> <p style="FONT-FAMILY: courier new">    }</p> <p style="FONT-FAMILY: courier new"> </p> <p style="FONT-FAMILY: courier new">#ifdef MOVABLE</p> <p style="FONT-FAMILY: courier new">    remote_integer(remote_integer&& other) {</p> <p style="FONT-FAMILY: courier new">        cout << "MOVE CONSTRUCTOR." << endl;</p> <p style="FONT-FAMILY: courier new"> </p> <p style="FONT-FAMILY: courier new">        m_p = NULL;</p> <p style="FONT-FAMILY: courier new">        *this = Move(other); // RIGHT</p> <p style="FONT-FAMILY: courier new">    }</p> <p style="FONT-FAMILY: courier new">#endif // #ifdef MOVABLE</p> <p style="FONT-FAMILY: courier new"> </p> <p style="FONT-FAMILY: courier new">    remote_integer& operator=(const remote_integer& other) {</p> <p style="FONT-FAMILY: courier new">        cout << "Copy assignment operator." << endl;</p> <p style="FONT-FAMILY: courier new"> </p> <p style="FONT-FAMILY: courier new">        if (this != &other) {</p> <p style="FONT-FAMILY: courier new">            delete m_p;</p> <p style="FONT-FAMILY: courier new"> </p> <p style="FONT-FAMILY: courier new">            if (other.m_p) {</p> <p style="FONT-FAMILY: courier new">                m_p = new int(*other.m_p);</p> <p style="FONT-FAMILY: courier new">            } else {</p> <p style="FONT-FAMILY: courier new">                m_p = NULL;</p> <p style="FONT-FAMILY: courier new">            }</p> <p style="FONT-FAMILY: courier new">        }</p> <p style="FONT-FAMILY: courier new"> </p> <p style="FONT-FAMILY: courier new">        return *this;</p> <p style="FONT-FAMILY: courier new">    }</p> <p style="FONT-FAMILY: courier new"> </p> <p style="FONT-FAMILY: courier new">#ifdef MOVABLE</p> <p style="FONT-FAMILY: courier new">    remote_integer& operator=(remote_integer&& other) {</p> <p style="FONT-FAMILY: courier new">        cout << "MOVE ASSIGNMENT OPERATOR." << endl;</p> <p style="FONT-FAMILY: courier new"> </p> <p style="FONT-FAMILY: courier new">        if (this != &other) {</p> <p style="FONT-FAMILY: courier new">            delete m_p;</p> <p style="FONT-FAMILY: courier new"> </p> <p style="FONT-FAMILY: courier new">            m_p = other.m_p;</p> <p style="FONT-FAMILY: courier new">            other.m_p = NULL;</p> <p style="FONT-FAMILY: courier new">        }</p> <p style="FONT-FAMILY: courier new"> </p> <p style="FONT-FAMILY: courier new">        return *this;</p> <p style="FONT-FAMILY: courier new">    }</p> <p style="FONT-FAMILY: courier new">#endif // #ifdef MOVABLE</p> <p style="FONT-FAMILY: courier new"> </p> <p style="FONT-FAMILY: courier new">    ~remote_integer() {</p> <p style="FONT-FAMILY: courier new">        cout << "Destructor." << endl;</p> <p style="FONT-FAMILY: courier new"> </p> <p style="FONT-FAMILY: courier new">        delete m_p;</p> <p style="FONT-FAMILY: courier new">    }</p> <p style="FONT-FAMILY: courier new"> </p> <p style="FONT-FAMILY: courier new">    int get() const {</p> <p style="FONT-FAMILY: courier new">        return m_p ? *m_p : 0;</p> <p style="FONT-FAMILY: courier new">    }</p> <p style="FONT-FAMILY: courier new"> </p> <p style="FONT-FAMILY: courier new">private:</p> <p style="FONT-FAMILY: courier new">    int * m_p;</p> <p style="FONT-FAMILY: courier new">};</p> <p style="FONT-FAMILY: courier new"> </p> <p style="FONT-FAMILY: courier new">remote_integer frumple(const int n) {</p> <p style="FONT-FAMILY: courier new">    if (n == 1729) {</p> <p style="FONT-FAMILY: courier new">        return remote_integer(1729);</p> <p style="FONT-FAMILY: courier new">    }</p> <p style="FONT-FAMILY: courier new"> </p> <p style="FONT-FAMILY: courier new">    remote_integer ret(n * n);</p> <p style="FONT-FAMILY: courier new"> </p> <p style="FONT-FAMILY: courier new">    return ret;</p> <p style="FONT-FAMILY: courier new">}</p> <p style="FONT-FAMILY: courier new"> </p> <p style="FONT-FAMILY: courier new">int main() {</p> <p style="FONT-FAMILY: courier new">    remote_integer x = frumple(5);</p> <p style="FONT-FAMILY: courier new"> </p> <p style="FONT-FAMILY: courier new">    cout << x.get() << endl;</p> <p style="FONT-FAMILY: courier new"> </p> <p style="FONT-FAMILY: courier new">    remote_integer y = frumple(1729);</p> <p style="FONT-FAMILY: courier new"> </p> <p style="FONT-FAMILY: courier new">    cout << y.get() << endl;</p> <p style="FONT-FAMILY: courier new">}</p> <p style="FONT-FAMILY: courier new"> </p> <p style="FONT-FAMILY: courier new">C:\Temp>cl /EHsc /nologo /W4 /O2 /DMOVABLE unified_right.cpp</p> <p style="FONT-FAMILY: courier new">unified_right.cpp</p> <p style="FONT-FAMILY: courier new"> </p> <p style="FONT-FAMILY: courier new">C:\Temp>unified_right</p> <p style="FONT-FAMILY: courier new">Unary constructor.</p> <p style="FONT-FAMILY: courier new">MOVE CONSTRUCTOR.</p> <p style="FONT-FAMILY: courier new">MOVE ASSIGNMENT OPERATOR.</p> <p style="FONT-FAMILY: courier new">Destructor.</p> <p style="FONT-FAMILY: courier new">25</p> <p style="FONT-FAMILY: courier new">Unary constructor.</p> <p style="FONT-FAMILY: courier new">1729</p> <p style="FONT-FAMILY: courier new">Destructor.</p> <p style="FONT-FAMILY: courier new">Destructor.</p> <p style="FONT-FAMILY: 宋体"> </p> <p style="FONT-FAMILY: 宋体">Q我交替?std::move() 和我自己?Move()Q因为它们的实现是等L(fng)Q?std::move() 是怎样工作的呢Q目前,我只能跟你说q是“法”。(后面会有完整的解释,q不复杂Q但它与模板参数推导和引用折叠(reference collapsingQ译注:引用的引用)?养I后面讲完{发的时候我们还会遇到这两个东西Q。我可以用一个具体的例子来略q?#8220;法”Q给定一?string cd的左|像前面重载决议例子中?up Qstd::move(up) 调用 string&& std::move(string&)Q这个函数返回一个不具名?rvalue 引用Q它是一?rvalue。给定一?string cd?rvalueQ像前面重蝲册例子中的 strange()Q?std::move(strange()) 调用 string&& std::move(string&&)Q同栯个函数还是返回一个不具名?rvalueQ还?rvalue?/p> <p style="FONT-FAMILY: 宋体"> </p> <p style="FONT-FAMILY: 宋体">std::move() 除了让你能用 move 复制函数来实?move 构造函C外,q能在其他地方发挥作用。无ZӞ只要你有一个左|而它的g不再重要了(例如Q它?yu)被销毁或被赋|Q你可以?std::move(你的左D辑ּ) 来?move 语意?/p> <p style="FONT-FAMILY: 宋体"> </p> <p style="FONT-FAMILY: 宋体"><strong>move </strong><strong>语意Q可Ud成员Q?/strong><strong>movable member)</strong></p> <p style="FONT-FAMILY: 宋体"><br></p> <p style="FONT-FAMILY: 宋体">C++0x 的标准类型(?vector, string, regexQ?都有 move 构造函数和 move 赋值函数。而且我们也已l看C如何在我们自qcM通过手动理资源来实?move 语意Q像前面?remote_integer c)。如果类中包含可Ud数据成员Q像 vector, string, regex, remote_integer Q时该怎么办呢Q编译器不会自动帮我们自动?move 构造函数和 move 赋值函敎ͼ所以我们必L动编写它们。很q运Q有?std::move() ~写它们是很Ҏ(gu)的?/p> <p style="FONT-FAMILY: 宋体"> </p> <p style="FONT-FAMILY: courier new">C:\Temp>type point.cpp</p> <p style="FONT-FAMILY: courier new">#include <stddef.h></p> <p style="FONT-FAMILY: courier new">#include <iostream></p> <p style="FONT-FAMILY: courier new">#include <ostream></p> <p style="FONT-FAMILY: courier new">using namespace std;</p> <p style="FONT-FAMILY: courier new"> </p> <p style="FONT-FAMILY: courier new">template <typename T> struct RemoveReference {</p> <p style="FONT-FAMILY: courier new">     typedef T type;</p> <p style="FONT-FAMILY: courier new">};</p> <p style="FONT-FAMILY: courier new"> </p> <p style="FONT-FAMILY: courier new">template <typename T> struct RemoveReference<T&> {</p> <p style="FONT-FAMILY: courier new">     typedef T type;</p> <p style="FONT-FAMILY: courier new">};</p> <p style="FONT-FAMILY: courier new"> </p> <p style="FONT-FAMILY: courier new">template <typename T> struct RemoveReference<T&&> {</p> <p style="FONT-FAMILY: courier new">     typedef T type;</p> <p style="FONT-FAMILY: courier new">};</p> <p style="FONT-FAMILY: courier new"> </p> <p style="FONT-FAMILY: courier new">template <typename T> typename RemoveReference<T>::type&& Move(T&& t) {</p> <p style="FONT-FAMILY: courier new">    return t;</p> <p style="FONT-FAMILY: courier new">}</p> <p style="FONT-FAMILY: courier new"> </p> <p style="FONT-FAMILY: courier new">class remote_integer {</p> <p style="FONT-FAMILY: courier new">public:</p> <p style="FONT-FAMILY: courier new">    remote_integer() {</p> <p style="FONT-FAMILY: courier new">        cout << "Default constructor." << endl;</p> <p style="FONT-FAMILY: courier new"> </p> <p style="FONT-FAMILY: courier new">        m_p = NULL;</p> <p style="FONT-FAMILY: courier new">    }</p> <p style="FONT-FAMILY: courier new"> </p> <p style="FONT-FAMILY: courier new">    explicit remote_integer(const int n) {</p> <p style="FONT-FAMILY: courier new">        cout << "Unary constructor." << endl;</p> <p style="FONT-FAMILY: courier new"> </p> <p style="FONT-FAMILY: courier new">        m_p = new int(n);</p> <p style="FONT-FAMILY: courier new">    }</p> <p style="FONT-FAMILY: courier new"> </p> <p style="FONT-FAMILY: courier new">    remote_integer(const remote_integer& other) {</p> <p style="FONT-FAMILY: courier new">        cout << "Copy constructor." << endl;</p> <p style="FONT-FAMILY: courier new"> </p> <p style="FONT-FAMILY: courier new">        if (other.m_p) {</p> <p style="FONT-FAMILY: courier new">            m_p = new int(*other.m_p);</p> <p style="FONT-FAMILY: courier new">        } else {</p> <p style="FONT-FAMILY: courier new">            m_p = NULL;</p> <p style="FONT-FAMILY: courier new">        }</p> <p style="FONT-FAMILY: courier new">    }</p> <p style="FONT-FAMILY: courier new"> </p> <p style="FONT-FAMILY: courier new">    remote_integer(remote_integer&& other) {</p> <p style="FONT-FAMILY: courier new">        cout << "MOVE CONSTRUCTOR." << endl;</p> <p style="FONT-FAMILY: courier new"> </p> <p style="FONT-FAMILY: courier new">        m_p = other.m_p;</p> <p style="FONT-FAMILY: courier new">        other.m_p = NULL;</p> <p style="FONT-FAMILY: courier new">    }</p> <p style="FONT-FAMILY: courier new"> </p> <p style="FONT-FAMILY: courier new">    remote_integer& operator=(const remote_integer& other) {</p> <p style="FONT-FAMILY: courier new">        cout << "Copy assignment operator." << endl;</p> <p style="FONT-FAMILY: courier new"> </p> <p style="FONT-FAMILY: courier new">        if (this != &other) {</p> <p style="FONT-FAMILY: courier new">            delete m_p;</p> <p style="FONT-FAMILY: courier new"> </p> <p style="FONT-FAMILY: courier new">            if (other.m_p) {</p> <p style="FONT-FAMILY: courier new">                m_p = new int(*other.m_p);</p> <p style="FONT-FAMILY: courier new">            } else {</p> <p style="FONT-FAMILY: courier new">                m_p = NULL;</p> <p style="FONT-FAMILY: courier new">            }</p> <p style="FONT-FAMILY: courier new">        }</p> <p style="FONT-FAMILY: courier new"> </p> <p style="FONT-FAMILY: courier new">        return *this;</p> <p style="FONT-FAMILY: courier new">    }</p> <p style="FONT-FAMILY: courier new"> </p> <p style="FONT-FAMILY: courier new">    remote_integer& operator=(remote_integer&& other) {</p> <p style="FONT-FAMILY: courier new">        cout << "MOVE ASSIGNMENT OPERATOR." << endl;</p> <p style="FONT-FAMILY: courier new"> </p> <p style="FONT-FAMILY: courier new">        if (this != &other) {</p> <p style="FONT-FAMILY: courier new">            delete m_p;</p> <p style="FONT-FAMILY: courier new"> </p> <p style="FONT-FAMILY: courier new">            m_p = other.m_p;</p> <p style="FONT-FAMILY: courier new">            other.m_p = NULL;</p> <p style="FONT-FAMILY: courier new">        }</p> <p style="FONT-FAMILY: courier new"> </p> <p style="FONT-FAMILY: courier new">        return *this;</p> <p style="FONT-FAMILY: courier new">    }</p> <p style="FONT-FAMILY: courier new"> </p> <p style="FONT-FAMILY: courier new">    ~remote_integer() {</p> <p style="FONT-FAMILY: courier new">        cout << "Destructor." << endl;</p> <p style="FONT-FAMILY: courier new"> </p> <p style="FONT-FAMILY: courier new">        delete m_p;</p> <p style="FONT-FAMILY: courier new">    }</p> <p style="FONT-FAMILY: courier new"> </p> <p style="FONT-FAMILY: courier new">    int get() const {</p> <p style="FONT-FAMILY: courier new">        return m_p ? *m_p : 0;</p> <p style="FONT-FAMILY: courier new">    }</p> <p style="FONT-FAMILY: courier new"> </p> <p style="FONT-FAMILY: courier new">private:</p> <p style="FONT-FAMILY: courier new">    int * m_p;</p> <p style="FONT-FAMILY: courier new">};</p> <p style="FONT-FAMILY: courier new"> </p> <p style="FONT-FAMILY: courier new">class remote_point {</p> <p style="FONT-FAMILY: courier new">public:</p> <p style="FONT-FAMILY: courier new">    remote_point(const int x_arg, const int y_arg)</p> <p style="FONT-FAMILY: courier new">        : m_x(x_arg), m_y(y_arg) { }</p> <p style="FONT-FAMILY: courier new"> </p> <p style="FONT-FAMILY: courier new">    remote_point(remote_point&& other)</p> <p style="FONT-FAMILY: courier new">        : m_x(Move(other.m_x)),</p> <p style="FONT-FAMILY: courier new">          m_y(Move(other.m_y)) { }</p> <p style="FONT-FAMILY: courier new"> </p> <p style="FONT-FAMILY: courier new">    remote_point& operator=(remote_point&& other) {</p> <p style="FONT-FAMILY: courier new">        m_x = Move(other.m_x);</p> <p style="FONT-FAMILY: courier new">        m_y = Move(other.m_y);</p> <p style="FONT-FAMILY: courier new">        return *this;</p> <p style="FONT-FAMILY: courier new">    }</p> <p style="FONT-FAMILY: courier new"> </p> <p style="FONT-FAMILY: courier new">    int x() const { return m_x.get(); }</p> <p style="FONT-FAMILY: courier new">    int y() const { return m_y.get(); }</p> <p style="FONT-FAMILY: courier new"> </p> <p style="FONT-FAMILY: courier new">private:</p> <p style="FONT-FAMILY: courier new">    remote_integer m_x;</p> <p style="FONT-FAMILY: courier new">    remote_integer m_y;</p> <p style="FONT-FAMILY: courier new">};</p> <p style="FONT-FAMILY: courier new"> </p> <p style="FONT-FAMILY: courier new">remote_point five_by_five() {</p> <p style="FONT-FAMILY: courier new">    return remote_point(5, 5);</p> <p style="FONT-FAMILY: courier new">}</p> <p style="FONT-FAMILY: courier new"> </p> <p style="FONT-FAMILY: courier new">remote_point taxicab(const int n) {</p> <p style="FONT-FAMILY: courier new">    if (n == 0) {</p> <p style="FONT-FAMILY: courier new">        return remote_point(1, 1728);</p> <p style="FONT-FAMILY: courier new">    }</p> <p style="FONT-FAMILY: courier new"> </p> <p style="FONT-FAMILY: courier new">    remote_point ret(729, 1000);</p> <p style="FONT-FAMILY: courier new"> </p> <p style="FONT-FAMILY: courier new">    return ret;</p> <p style="FONT-FAMILY: courier new">}</p> <p style="FONT-FAMILY: courier new"> </p> <p style="FONT-FAMILY: courier new">int main() {</p> <p style="FONT-FAMILY: courier new">    remote_point p = taxicab(43112609);</p> <p style="FONT-FAMILY: courier new"> </p> <p style="FONT-FAMILY: courier new">    cout << "(" << p.x() << ", " << p.y() << ")" << endl;</p> <p style="FONT-FAMILY: courier new"> </p> <p style="FONT-FAMILY: courier new">    p = five_by_five();</p> <p style="FONT-FAMILY: courier new"> </p> <p style="FONT-FAMILY: courier new">    cout << "(" << p.x() << ", " << p.y() << ")" << endl;</p> <p style="FONT-FAMILY: courier new">}</p> <p style="FONT-FAMILY: courier new"> </p> <p style="FONT-FAMILY: courier new">C:\Temp>cl /EHsc /nologo /W4 /O2 point.cpp</p> <p style="FONT-FAMILY: courier new">point.cpp</p> <p style="FONT-FAMILY: courier new"> </p> <p style="FONT-FAMILY: courier new">C:\Temp>point</p> <p style="FONT-FAMILY: courier new">Unary constructor.</p> <p style="FONT-FAMILY: courier new">Unary constructor.</p> <p style="FONT-FAMILY: courier new">MOVE CONSTRUCTOR.</p> <p style="FONT-FAMILY: courier new">MOVE CONSTRUCTOR.</p> <p style="FONT-FAMILY: courier new">Destructor.</p> <p style="FONT-FAMILY: courier new">Destructor.</p> <p style="FONT-FAMILY: courier new">(729, 1000)</p> <p style="FONT-FAMILY: courier new">Unary constructor.</p> <p style="FONT-FAMILY: courier new">Unary constructor.</p> <p style="FONT-FAMILY: courier new">MOVE ASSIGNMENT OPERATOR.</p> <p style="FONT-FAMILY: courier new">MOVE ASSIGNMENT OPERATOR.</p> <p style="FONT-FAMILY: courier new">Destructor.</p> <p style="FONT-FAMILY: courier new">Destructor.</p> <p style="FONT-FAMILY: courier new">(5, 5)</p> <p style="FONT-FAMILY: courier new">Destructor.</p> <p style="FONT-FAMILY: courier new">Destructor.</p> <p style="FONT-FAMILY: 宋体"> </p> <p style="FONT-FAMILY: 宋体">现在你看到啦Q按成员UdQmemberwise moveQ是很容易做到的。注意, remote_point ?move 赋值函数没有进行自我赋值检查,是因?remote_integer 已经查过了。也要注意到 remote_point 隐式声明的拷贝构造函敎ͼ拯赋值函数和析构函数都正常运作?/p> <p style="FONT-FAMILY: 宋体"> </p> <p style="FONT-FAMILY: 宋体">到现在,你应该对 move 语意已经非常熟?zhn)了。(希望不是抓狂啊!Qؓ了测试你新获得的q个不可思议的技能,请ؓ前面的例子写一?+() 操作W函数当作练习吧?/p> <p style="FONT-FAMILY: 宋体"> </p> <p style="FONT-FAMILY: 宋体">最后的提醒Q只要你的类支持 move 语意Q你应该实?move 构造函数和 move 赋值函数。因Z仅仅是你q_使用q些cL可从 move 语意中获利, STL 容器和算法也能从中获利,通过廉h(hun)?move 省下昂贵的拷贝开销?/p> <p style="FONT-FAMILY: 宋体"><br></p> <p style="FONT-FAMILY: 宋体; TEXT-ALIGN: center">(转蝲h明出处,作者与译者信息,请勿用于商业用? </p> <p style="FONT-FAMILY: 宋体"><br></p> <p style="FONT-FAMILY: 宋体; TEXT-ALIGN: center"> < <a href="http://www.shnenglu.com/kesalin/archive/2009/06/01/86461.html">前一?/a>  后一?><br></p> <br style="FONT-FAMILY: 宋体"> <img src ="http://www.shnenglu.com/kesalin/aggbug/86720.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/kesalin/" target="_blank">|朝?/a> 2009-06-04 09:37 <a href="http://www.shnenglu.com/kesalin/archive/2009/06/04/86720.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>【译】VC10中的C++0xҎ(gu)?part 2Q?Q?叛_引?/title><link>http://www.shnenglu.com/kesalin/archive/2009/06/01/86461.html</link><dc:creator>|朝?/dc:creator><author>|朝?/author><pubDate>Mon, 01 Jun 2009 12:40:00 GMT</pubDate><guid>http://www.shnenglu.com/kesalin/archive/2009/06/01/86461.html</guid><wfw:comment>http://www.shnenglu.com/kesalin/comments/86461.html</wfw:comment><comments>http://www.shnenglu.com/kesalin/archive/2009/06/01/86461.html#Feedback</comments><slash:comments>6</slash:comments><wfw:commentRss>http://www.shnenglu.com/kesalin/comments/commentRss/86461.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/kesalin/services/trackbacks/86461.html</trackback:ping><description><![CDATA[     摘要: q一pd文章介绍Microsoft Visual Studio 2010 中支持的C++ 0xҎ(gu),目前有三部分?<br>Part 1Q介l了LambdasQ?赋予新意义的autoQ以?static_assertQ?<br>Part 2Q介l了叛_引用(Rvalue ReferencesQ; <br>Part 3Q介l了表达式类型(decltypeQ?<br> <br>本文为Part 2 的第一c?nbsp; <a href='http://www.shnenglu.com/kesalin/archive/2009/06/01/86461.html'>阅读全文</a><img src ="http://www.shnenglu.com/kesalin/aggbug/86461.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/kesalin/" target="_blank">|朝?/a> 2009-06-01 20:40 <a href="http://www.shnenglu.com/kesalin/archive/2009/06/01/86461.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>【译】VC10中的C++0xҎ(gu)?part 1QLambdasQautoQ以?static_asserthttp://www.shnenglu.com/kesalin/archive/2009/05/28/85983.html|朝?/dc:creator>|朝?/author>Thu, 28 May 2009 03:27:00 GMThttp://www.shnenglu.com/kesalin/archive/2009/05/28/85983.htmlhttp://www.shnenglu.com/kesalin/comments/85983.htmlhttp://www.shnenglu.com/kesalin/archive/2009/05/28/85983.html#Feedback14http://www.shnenglu.com/kesalin/comments/commentRss/85983.htmlhttp://www.shnenglu.com/kesalin/services/trackbacks/85983.html阅读全文

]]>
Head First design patternsMW记http://www.shnenglu.com/kesalin/archive/2008/07/20/56714.html|朝?/dc:creator>|朝?/author>Sun, 20 Jul 2008 15:31:00 GMThttp://www.shnenglu.com/kesalin/archive/2008/07/20/56714.htmlhttp://www.shnenglu.com/kesalin/comments/56714.htmlhttp://www.shnenglu.com/kesalin/archive/2008/07/20/56714.html#Feedback0http://www.shnenglu.com/kesalin/comments/commentRss/56714.htmlhttp://www.shnenglu.com/kesalin/services/trackbacks/56714.html阅读全文

]]>
C语言声明的优先规则http://www.shnenglu.com/kesalin/archive/2008/06/30/54992.html|朝?/dc:creator>|朝?/author>Mon, 30 Jun 2008 15:33:00 GMThttp://www.shnenglu.com/kesalin/archive/2008/06/30/54992.htmlhttp://www.shnenglu.com/kesalin/comments/54992.htmlhttp://www.shnenglu.com/kesalin/archive/2008/06/30/54992.html#Feedback1http://www.shnenglu.com/kesalin/comments/commentRss/54992.htmlhttp://www.shnenglu.com/kesalin/services/trackbacks/54992.html
A 声明从它的名字开始读取,然后按照优先U顺序依ơ读取;

B 优先U从高到低依ơ是Q?

B.1 声明中被括号括v来的那部分;

B.2 后缀操作W:括号()表示q是一个函敎ͼ而方括号[]表示q是一个数l;

B.3 前缀操作W:星号*标识“指?..的指针”;

C 如果const?或?volatile关键字的后面紧跟cd说明W?如intQlong{?Q那么它作用于类型说明符Q在其他情况下,const??volatile关键字作用于它左边紧?c)指针星号?
  阅读全文

]]>
【译】在C++中用LUAhttp://www.shnenglu.com/kesalin/archive/2008/06/17/53688.html|朝?/dc:creator>|朝?/author>Tue, 17 Jun 2008 04:38:00 GMThttp://www.shnenglu.com/kesalin/archive/2008/06/17/53688.htmlhttp://www.shnenglu.com/kesalin/comments/53688.htmlhttp://www.shnenglu.com/kesalin/archive/2008/06/17/53688.html#Feedback0http://www.shnenglu.com/kesalin/comments/commentRss/53688.htmlhttp://www.shnenglu.com/kesalin/services/trackbacks/53688.html
原文链接Qhttp://www.spheregames.com/index.php?p=templates/pages/tutorials

作者:http://www.spheregames.com

译Q飘飘白云(http://www.shnenglu.com/kesalin Q?



译注Q翻译本文ƈ未获得原作者的许可Q翻译本文来仅供个h学习消遣Q故谢却转蝲?

原文中的CZ代码汲取了《游戏编E精_?5》中Matthew Harmon写的 “Building LUA into Games”一文的x与部分代码实玎ͼ我将“Building LUA into Games”一文的CZ代码应用到最新的LUA版本Q也打包贴在q里Q供大家参考?

Using LUA with C++Q示例代码下?

Building LUA into Gam  阅读全文

]]>
ŷһþ| þþƷѿ| 99þùѸ| 99þ777ɫ| þþŷղa | ˾þۺ| þþþ| þþƷ99ɫĻ| þùƷþþƷ| Ʒһþþ| þ޾Ʒ| þùAV䡪ٶ| vaþþþ | þþƷAV| þþù׮| ŷAŷaþ| þݺҹҹվ| պƷþþþþ| þþþ޾Ʒһ| 99þ뾫Ʒϵ| ˺ݺۺϾþ| 9191ƷѾþ| þþþþһƷ| ŷ˾þþƷ| þɫۺ| 69þҹɫƷ69| Ʒ99þþþþլ | þŷ޹ۺ| ٸۺϾþĻ| Ʒþ| AVɫۺϾþAVɫۺ| ݹƷþþþ| ˾þۺӰԺ| ҹavþþþ| þۺϾɫۺ97_þþ| ƷþþþþĻ | ղƷþþþþþ| þù޾Ʒ| ŷɫۺϾþþþþ | 99þĻ| ɫۺϾþþþĻ|