<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">
    <title>程序设计语言</title>
    <link href="http://www.yeeyan.com/groups/show/lang" />
    <subtitle />
    <id>tag:feed.yeeyan.com:group/lang</id>
    <modified>2009-07-14T23:46:57+00:00</modified>
    <generator>FeedCreator 1.7.2</generator>
    <link rel="self" href="http://feeds.feedburner.com/yeeyan_lang" type="application/atom+xml" /><entry>
        <title>VC10中的C&amp;#43;&amp;#43;0x特性 part 3 : 声明之类型</title>
        <link href="http://feedproxy.google.com/~r/yeeyan_lang/~3/FkFsq-9mhxc/44051" />
        <created>2009-06-03T06:25:46+00:00</created>
        <issued>2009-06-03T06:25:46+00:00</issued>
        <modified>2009-06-03T06:25:46+00:00</modified>
        <published>2009-06-03T06:25:46+00:00</published>
        <id>tag:feed.yeeyan.com:translation/44051</id>
        <category term="科学技术" scheme="feed.yeeyan.com" label="科学技术" />
        <author>
            <name>飘飘白云</name>
            <uri>http://www.yeeyan.com/space/show/kesalin</uri>
        </author>
        <content type="html">
            <![CDATA[<p>原文作者：Visual C&#43;&#43; Team Blog<br />原文链接：<a href="http://blogs.msdn.com/vcblog/archive/2009/04/22/decltype-c-0x-features-in-vc10-part-3.aspx">decltype: C&#43;&#43;0x Features in VC10, Part 3</a><br/>译者：<a href="http://www.yeeyan.com/space/show/kesalin">飘飘白云</a></p><p style="text-align:center;"><span style="font-size:medium;"><strong>VC10中的C++0x特性 part 3 : 声明之类型</strong><br /></span></p>
<p style="text-align:center;"><span style="font-size:medium;">来源：<a title="vcvlog" href="http://blogs.msdn.com/vcblog/archive/2009/02/03/rvalue-references-c-0x-features-in-vc10-part-2.aspx" target="_blank">vcblog</a> 翻译：<a href="http://www.cppblog.com/kesalin" target="_blank">飘飘白云</a> kesalin@gmail.com</span></p>
<p><span style="font-size:medium;">这个系列的</span></p>
<p><span style="font-size:medium;">第一部分（ <a href="http://www.yeeyan.com/articles/view/kesalin/43288" target="_blank">1</a>， <a href="http://www.yeeyan.com/articles/view/kesalin/43571" target="_blank">2</a>， <a href="http://www.yeeyan.com/articles/view/kesalin/43573" target="_blank">3</a> ）介绍了 <strong>lambda</strong>, <strong>auto </strong>和 <strong>static_assert</strong>。</span></p>
<p><span style="font-size:medium;">第二部分</span><span style="font-size:medium;">（</span><span style="font-size:medium;"><a href="http://www.yeeyan.com/articles/view/kesalin/43500">1</a>， <a href="http://www.yeeyan.com/articles/view/kesalin/43772" target="_blank">2</a> ， <a href="http://www.yeeyan.com/articles/view/kesalin/43774" target="_blank">3</a></span><span style="font-size:medium;"> ， <a target="_blank">4</a> ， <a target="_blank">5</a> ）</span><span style="font-size:medium;">介绍了右值引用。</span></p>
<p><span style="font-size:medium;">第三部分（<a href="http://www.yeeyan.com/articles/view/kesalin/44051" target="_blank">本文</a>）介绍了声明之类型(decltype)<br /></span><span style="font-size:medium;"><br />今天我要讲 decltype，它让完美转发函数能够返回任意类型的东西。对编写高度泛型的人来说这是很有趣的的特性。<br /><br /><strong>返回类型问题</strong><br /><br />C++98/03 有一个有意思的盲点：给定一个像 <strong>x * y</strong> 的表达式， <strong>x</strong> 和 <strong>y</strong> 是任意类型，你却没法知道 <strong>x * y</strong> 的类型。假如 <strong>x</strong> 是 <strong>Watts </strong>类型的， <strong>y</strong> 是<strong> Seconds</strong> 类型的，那 <strong>x * y</strong> 的类型可能会是 Joules 类型的。 给定声明 <strong>print(const T&amp; t)</strong>，调用 <strong>print( x * y )</strong> ，在这里 <strong>T</strong> 会被推导为 <strong>Joules</strong> 类型。但反过来却不是这样的：当你写个函数 <strong>multiply(const A&amp; a, const B&amp; b) </strong>，你无法指定它的通用返回类型。即使是实例化成 <strong>multiply&lt;A, B&gt;()</strong> ，编译器也晓得 <strong>x * y</strong> 的类型，但你就是没办法得到那样的信息（指返回类型）。C++0x 中的关键词 <strong>decltype </strong>扫除了这个盲点，让你能够说“ <strong>multiply()</strong> 返回 <strong>x * y</strong> 类型的东西”。（<strong>decltype </strong>是 "declared type" 的缩写，我把它读作谐音 “speckle type”。）<br /><br /><strong>decltype：模式</strong><br /><br />下面是一个完全泛化的封装 +() 操作符的函数因子。这个“加法”因子不是一个模板，但它有一个模板函数，这个模板函数带两个任意类型（当然是不同类型的）参数，并把它们想加，然后返回任意类型（可能跟两个参数的类型完全不同）的结果。<br /></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">C:\Temp&gt;type plus.cpp</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">#include &lt;algorithm&gt;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">#include &lt;iostream&gt;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">#include &lt;iterator&gt;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">#include &lt;ostream&gt;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">#include &lt;string&gt;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">#include &lt;utility&gt;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">#include &lt;vector&gt;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">using namespace std;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><br /></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">struct Plus {</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    template &lt;typename T, typename U&gt;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    <strong>auto</strong> operator()(T&amp;&amp; t, U&amp;&amp; u) const</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    <strong>-&gt; decltype(forward&lt;T&gt;(t) + forward&lt;U&gt;(u))</strong> {</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">        return forward&lt;T&gt;(t) + forward&lt;U&gt;(u);</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    }</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">};</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><br /></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">int main() {</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    vector&lt;int&gt; i;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    i.push_back(1);</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    i.push_back(2);</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    i.push_back(3);</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><br /></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    vector&lt;int&gt; j;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    j.push_back(40);</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    j.push_back(50);</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    j.push_back(60);</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><br /></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    vector&lt;int&gt; k;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><br /></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    vector&lt;string&gt; s;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    s.push_back("cut");</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    s.push_back("flu");</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    s.push_back("kit");</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><br /></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    vector&lt;string&gt; t;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    t.push_back("e");</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    t.push_back("ffy");</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    t.push_back("tens");</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><br /></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    vector&lt;string&gt; u;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><br /></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    transform(i.begin(), i.end(), j.begin(), back_inserter(k), Plus());</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    transform(s.begin(), s.end(), t.begin(), back_inserter(u), Plus());</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><br /></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    for_each(k.begin(), k.end(), [](int n) { cout &lt;&lt; n &lt;&lt; " "; });</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    cout &lt;&lt; endl;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><br /></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    for_each(u.begin(), u.end(), [](const string&amp; r) { cout &lt;&lt; r &lt;&lt; " "; });</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    cout &lt;&lt; endl;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">}</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><br /></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">C:\Temp&gt;cl /EHsc /nologo /W4 plus.cpp</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">plus.cpp</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><br /></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">C:\Temp&gt;plus</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">41 52 63</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">cute fluffy kittens</span></p>
<p><span style="font-size:medium;"><br />拿 C++98/03 <strong>&lt;functional&gt;</strong> 中的 <strong>std::plus&lt;T&gt;</strong> (在 C++0x 没有变动)来作对比，后者是一个类模板，你不得不传递模板参数类型来调用 <strong>plus&lt;int&gt;()</strong> 和 <strong>plus&lt;string&gt;()</strong>，重复声明一次元素类型。并且后者那个形式为 <strong>T operator()(const T&amp; x, const T&amp; y) </strong>的非模板函数调用操作符，如果不借助于隐式类型转换，就不能将两种不同类型的东西相加，更不用说 3 种不同类型的情况了（译注：两个参数类型 + 一个返回类型）。（你可以传递 <strong>string</strong> 和 <strong>const char *</strong> 类型的实参来调用 <strong>const plus&lt;string&gt;()</strong>，那样的话就会在串接操作之前，基于第二个参数(<strong>const char *</strong>)构建一个临时 <strong>string</strong>，这样做在性能上不可取）。 再者，因为它的参数是 <strong>const T&amp;</strong> 形式的，这就不能使用 C++0x 的 <strong>move </strong>语意来获得好处。<strong>Plus</strong> 避免了上述问题：调用 <strong>Plus()</strong> 不需要重复声明元素的类型，它也可以处理 “3 种” 不同类型的情况，并且它用了完美转发，因而能够使用 move 语意。<br /><br /><strong>trailing return type<br /><br /></strong>现在让我们再来看看这个模板函数调用操作符：<br /></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">template &lt;typename T, typename U&gt;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><strong>auto</strong> operator()(T&amp;&amp; t, U&amp;&amp; u) const</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><strong>-&gt; decltype(forward&lt;T&gt;(t) + forward&lt;U&gt;(u))</strong> {</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    return forward&lt;T&gt;(t) + forward&lt;U&gt;(u);</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">}</span></p>
<p><span style="font-size:medium;">这里的 <strong>auto</strong> 与 <strong>for ( auto i = v.begin(); i != v.end(); ++i)</strong> 中的含义完全不同, 在 for 中它是指“把用来初始化对象的类型当做对象的类型”，而在这里它是指“这个函数有 <strong>trailing-return-type</strong>，只有指定实参之后，才能确定它返回什么类型”(C++0x 提案 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2009/n2857.pdf" target="_blank">N2857</a> 中把这个称作 “<em><strong>late-specified return type</strong></em>”，但它将被重命名为 “<strong>trailing-retrun-type</strong>”（提案 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2009/n2859.pdf" target="_blank">N2859</a> ）)。这里看起来和 lambda 函数是如何指定返回类型的很相似，其实它们就是一样的。<strong>lambda </strong>函数的返回类型必须出现在 <strong>lambda </strong>导引符 <strong>[]</strong> 之后（右边）。在这里，<strong>decltype-powered</strong> 类型也必须出现在函数参数 <strong>t</strong> 和 <strong>u</strong> 之后（右边）。<strong>auto</strong><strong>T</strong> 和 <strong>U</strong> 对它是可见的，但是函数参数 <strong>t</strong> 和 <strong>u </strong>还不可见，这就是为什么需要 <strong>decltype </strong>的原因。（从技术上来讲， <strong>decltype(forward&lt;T&gt;(*static_cast&lt;T *&gt;(0)) + forward&lt;U&gt;(*static_cast&lt;U *&gt;(0))）</strong> 可以在左边出现，但那看起来会让人不舒服）。<br /><br />至于在返回语句中还要使用与传给 <strong>decltype </strong>的表达式相同的形式，是为了确保在任何情况下都能正确工作。（<span>突击测验：为什么 decltype(t + u) 就不对呢？</span>）。这里的重复是不可避免的，但因为集中-只出现一次且代码位置靠近，所以不会有什么危险。<br /><br /><strong>另一个例子</strong><br /><br />考虑到例子的完整性，下面是一个 “3种” 不同类型的示例：</span><span style="font-size:medium;">  <br /></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">C:\Temp&gt;type mult.cpp</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">#include &lt;algorithm&gt;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">#include &lt;iostream&gt;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">#include &lt;iterator&gt;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">#include &lt;ostream&gt;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">#include &lt;utility&gt;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">#include &lt;vector&gt;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">using namespace std;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><br /></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">struct Multiplies {</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    template &lt;typename T, typename U&gt;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    auto operator()(T&amp;&amp; t, U&amp;&amp; u) const</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    -&gt; decltype(forward&lt;T&gt;(t) * forward&lt;U&gt;(u)) {</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">        return forward&lt;T&gt;(t) * forward&lt;U&gt;(u);</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    }</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">};</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><br /></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">class Watts {</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">public:</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    explicit Watts(const int n) : m_n(n) { }</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    int get() const { return m_n; }</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">private:</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    int m_n;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">};</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><br /></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">class Seconds {</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">public:</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    explicit Seconds(const int n) : m_n(n) { }</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    int get() const { return m_n; }</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">private:</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    int m_n;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">};</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><br /></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">class Joules {</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">public:</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    explicit Joules(const int n) : m_n(n) { }</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    int get() const { return m_n; }</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">private:</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    int m_n;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">};</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><br /></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">Joules operator*(const Watts&amp; w, const Seconds&amp; s) {</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    return Joules(w.get() * s.get());</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">}</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><br /></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">int main() {</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    vector&lt;Watts&gt; w;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    w.push_back(Watts(2));</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    w.push_back(Watts(3));</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    w.push_back(Watts(4));</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><br /></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    vector&lt;Seconds&gt; s;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    s.push_back(Seconds(5));</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    s.push_back(Seconds(6));</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    s.push_back(Seconds(7));</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><br /></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    vector&lt;Joules&gt; j;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><br /></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    transform(w.begin(), w.end(), s.begin(), back_inserter(j), Multiplies());</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><br /></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    for_each(j.begin(), j.end(), [](const Joules&amp; r) { cout &lt;&lt; r.get() &lt;&lt; endl; });</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">}</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><br /></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">C:\Temp&gt;cl /EHsc /nologo /W4 mult.cpp</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">mult.cpp</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><br /></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">C:\Temp&gt;mult</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">10</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">18</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">28</span></p>
<p><span style="font-size:medium;"><br />你可能会问“所有的这些处理真的有必要么”，答案是 Yes ，有必要。我已经介绍了完美转发和 decltype 是如何让算术运算函数因子使用起来更容易（不用重复声明元素类型），更灵活（可以混合使用不同的参数和返回类型），更有效率（使用 move 语意）。最重要的是，完美转发和 decltype 让你能够编写更简洁明了的代码，而不灵活和低效的代码不是简洁明了的-这点是我们无法忽视的。<br /><br /><strong>高级规则</strong><br /><br /><strong>decltype </strong>是有一些规则来驱动的。然而，如果你遵照上面的模式就没关系，能正常工作。我很少那样说 C++ ，但是在这里是这样的。<br /><br />虽然大多数 <strong>decltype </strong>应用遵循上面介绍的模式，但 <strong>decltype </strong>还可以用于其他环境。在那些情况下，你就用到了 <strong>decltype</strong></span><span style="font-size:medium;"> 的高级模式，你应该全面地阅读那些规则，</span><span style="font-size:medium;">它们在 C++0x 提案 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2009/n2857.pdf" target="_blank">N2857</a>  </span><span style="font-size:medium;font-family:Verdana, 'sans-serif';">7.1.6.2 [dcl.type.simple]/4 中</span><span style="font-size:medium;">被给出。<br /><br /><strong>等等，还有一些要说的</strong><br /><br /><strong>decltype </strong>是第五个且是最后一个添加到VC10中的 C++0x 核心语言特性。虽然VC10 CTP中还没有，但 VC10 Bata 1中会有。而且 VC10 Beta 1 中还有很多 C++0x 标准库特性，我会在后续文章中介绍它们。</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Verdana, 'sans-serif';"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Verdana, 'sans-serif';">Stephan T. Lavavej</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Verdana, 'sans-serif';">Visual C++ Libraries Developer</span></p>
<p><span style="font-size:medium;">Published Wednesday, April 22, 2009 10:06 AM 			by 			<a href="http://blogs.msdn.com/user/Profile.aspx?UserID=33825">vcblog</a></span></p><p><a href="http://www.yeeyan.com/articles/view/kesalin/44051#newComment">添加评论</a></p>
<p><embed id="movie_rss" height="60" width="468" quality="high" bgcolor="#ffffff" name="mymovie" style="" src="http://www.yeeyan.com/files/newindexads/vancl_090622_468_rss.swf" type="application/x-shockwave-flash"/></p>
]]>
        </content>
    <feedburner:origLink>http://www.yeeyan.com/articles/view/kesalin/44051</feedburner:origLink></entry>
    <entry>
        <title>如何混淆电子邮件来防止垃圾发送者</title>
        <link href="http://feedproxy.google.com/~r/yeeyan_lang/~3/JhLOu5e8KD8/44259" />
        <created>2009-06-02T15:33:21+00:00</created>
        <issued>2009-06-02T15:33:21+00:00</issued>
        <modified>2009-06-02T15:33:21+00:00</modified>
        <published>2009-06-02T15:33:21+00:00</published>
        <id>tag:feed.yeeyan.com:translation/44259</id>
        <category term="电脑网络" scheme="feed.yeeyan.com" label="电脑网络" />
        <author>
            <name>cssrain</name>
            <uri>http://www.yeeyan.com/space/show/13127</uri>
        </author>
        <content type="html">
            <![CDATA[<p>原文作者：sitepoint.com<br />原文链接：<a href="http://www.sitepoint.com/blogs/2009/05/05/stop-spam-harvesting-email-obfuscation/">How to stop spam harvesting email obfuscation</a><br/>译者：<a href="http://www.yeeyan.com/space/show/13127">cssrain</a></p><p> </p>
<p class="MsoNormal"><span>一直以来我都认为</span><span lang="en-us" xml:lang="en-us">” <a href="mailto:">mailto:</a> “</span><span>是一个神圣的链接。通过它，我可以在网页中发布我的</span><span lang="en-us" xml:lang="en-us">email</span><span>地址，并且任何人都可以通过单击这个链接联系我。当然前提是在一个纯洁的</span><span lang="en-us" xml:lang="en-us">Web</span><span>环境下</span><span lang="en-us" xml:lang="en-us">---</span><span>在垃圾邮件发送者出来之前。举个例子说：今天你在你的网页中使用了</span><span lang="en-us" xml:lang="en-us">” <a href="mailto:">mailto:</a> “</span><span>，那么</span><span lang="en-us" xml:lang="en-us">30</span><span>秒后你将收到第一封伟哥信息。垃圾邮件发送者的速度之快另你惊讶。从今以后，你将收到越来越多的垃圾邮件。那么我们有什么办法，在自己的网页中发布自己邮箱的同时，不引起垃圾邮件发布者的注意呢？</span></p>
<p class="MsoNormal"><span lang="en-us" xml:lang="en-us"> </span></p>
<p class="MsoNormal"><span>最明显的解决办法是在你的</span><span lang="en-us" xml:lang="en-us">HTML</span><span>中使用机器不可读的</span><span lang="en-us" xml:lang="en-us">Email</span><span>。比如：</span><span lang="en-us" xml:lang="en-us">“bob (at) bobsdomain dot com”</span><span>。虽然这可以使垃圾邮件发送者不再那么容易，但它同时也会为难您的用户。</span></p>
<p class="MsoNormal"><span lang="en-us" xml:lang="en-us"><br /></span><span>另一种选择是使用</span><span lang="en-us" xml:lang="en-us">JavaScript</span><span>生成的电子邮件地址</span><span>，然后对字符串加点编码。如：</span></p>
<p class="MsoNormal"><span lang="en-us" xml:lang="en-us">&lt;p&gt;contact </span><span>：</span><span lang="en-us" xml:lang="en-us"> </span></p>
<p class="MsoNormal"><span lang="en-us" xml:lang="en-us">&lt;script type=<span class="string">"text/javascript"</span>&gt; </span></p>
<p class="MsoNormal"><span lang="en-us" xml:lang="en-us">document.write(<span class="string">'&lt;a href="mai'</span>+"lto<span class="string">"+"</span>bob<span class="string">"+'@'+'bobsdomain.com"</span>&gt;bob@'+<span class="string">"bobsdomain.com&lt;/a&gt;"</span>);</span></p>
<p class="MsoNormal"><span lang="en-us" xml:lang="en-us">&lt;/script&gt;</span></p>
<p class="MsoNormal"><span lang="en-us" xml:lang="en-us">&lt;/p&gt; </span></p>
<p class="MsoNormal"><span lang="en-us" xml:lang="en-us"> </span></p>
<p class="MsoNormal"><span>这将阻止大多数垃圾邮件发送者，但如果用户禁用</span><span lang="en-us" xml:lang="en-us">JavaScript</span><span>将不会看到您的地址。</span><span lang="en-us" xml:lang="en-us">(</span><span>我不推荐使用</span><span> <span lang="en-us" xml:lang="en-us">document.write() )</span></span></p>
<p class="MsoNormal"><span lang="en-us" xml:lang="en-us"> </span></p>
<p class="MsoNormal"><span>一个更好的解决办法是使用它们两者相结合的技术，以阻止垃圾邮件，同时不会造成用户的困难。首先在我的网页中使用一个人性化的，同时垃圾邮件发送者不能收集的</span><span lang="en-us" xml:lang="en-us">email</span><span>地址。我们还将它链接到一个联络网页，例如：</span></p>
<p class="MsoNormal"><span lang="en-us" xml:lang="en-us">&lt;p&gt;Contact &lt;a href="contact.html" class="email"&gt;bob (at) bobsdomain dot com&lt;/a&gt;&lt;/p&gt; </span></p>
<p class="MsoNormal"><span lang="en-us" xml:lang="en-us"> </span></p>
<p class="MsoNormal"><span>请注意，我们为链接添加了一个</span><span lang="en-us" xml:lang="en-us">class</span><span>，并设置为</span><span lang="en-us" xml:lang="en-us">”email”</span><span>。</span></p>
<p class="MsoNormal"><span>接下来写一个</span><span lang="en-us" xml:lang="en-us">JavaScript</span><span>函数搜寻网页的伪装的电子邮件，并将它转换成真正的</span><span lang="en-us" xml:lang="en-us">” <a href="mailto:">mailto:</a> “</span><span>链接。我们将创建一个</span><span lang="en-us" xml:lang="en-us">' email.js '</span><span>文件，将它包括在我们的</span><span lang="en-us" xml:lang="en-us">HTML</span><span>里</span><span>：</span><span lang="en-us" xml:lang="en-us"><br /> &lt;script type="text/javascript" src="email.js"&gt;&lt;/script&gt; <br /><br /></span><span>所需要的代码很短，代码如下：</span></p>
<p class="MsoNormal"><span lang="en-us" xml:lang="en-us">&lt;script type="text/javascript"&gt;</span></p>
<p class="MsoNormal"><span lang="en-us" xml:lang="en-us">function EmailUnobsfuscate() {</span></p>
<p class="MsoNormal"><span lang="en-us" xml:lang="en-us"><span>         </span>var link = document.getElementsByTagName &amp;&amp; document.getElementsByTagName("a");//</span><span>查找所有的</span><span lang="en-us" xml:lang="en-us">a</span></p>
<p class="MsoNormal"><span lang="en-us" xml:lang="en-us"><span>         </span>var email, e;</span></p>
<p class="MsoNormal"><span lang="en-us" xml:lang="en-us"><span>         </span>for (e = 0; link &amp;&amp; e &lt; link.length; e++) {</span></p>
<p class="MsoNormal"><span lang="en-us" xml:lang="en-us"><span>                   </span>// </span><span>判断当前</span><span lang="en-us" xml:lang="en-us">link</span><span>的</span><span lang="en-us" xml:lang="en-us">class</span><span>是否含有</span><span lang="en-us" xml:lang="en-us">"email"</span></p>
<p class="MsoNormal"><span lang="en-us" xml:lang="en-us"><span>                   </span>if ((" "+link[e].className+" ").indexOf(" email ") &gt;= 0) {</span></p>
<p class="MsoNormal"><span lang="en-us" xml:lang="en-us"><span>                            </span>// </span><span>获取全小写的</span><span lang="en-us" xml:lang="en-us">email</span><span>地址</span></p>
<p class="MsoNormal"><span lang="en-us" xml:lang="en-us"><span>                            </span>email = link[e].firstChild.nodeValue.toLowerCase() || "";</span></p>
<p class="MsoNormal"><span lang="en-us" xml:lang="en-us"><span>                            </span>// </span><span>转换</span><span lang="en-us" xml:lang="en-us">email</span><span>地址</span></p>
<p class="MsoNormal"><span lang="en-us" xml:lang="en-us"><span>                            </span>email = email.replace(/dot/ig, ".");//</span><span>将</span><span lang="en-us" xml:lang="en-us">dot</span><span>转为</span><span lang="en-us" xml:lang="en-us">.</span></p>
<p class="MsoNormal"><span lang="en-us" xml:lang="en-us"><span>                            </span>email = email.replace(/\(at\)/ig, "@");//</span><span>将</span><span lang="en-us" xml:lang="en-us">(at)</span><span>转为</span><span lang="en-us" xml:lang="en-us">@</span></p>
<p class="MsoNormal"><span lang="en-us" xml:lang="en-us"><span>                            </span>email = email.replace(/\s/g, "");//</span><span>将空格转为</span><span lang="en-us" xml:lang="en-us">""</span></p>
<p class="MsoNormal"><span lang="en-us" xml:lang="en-us"><span>                            </span>//</span><span>判断是否为有效</span><span lang="en-us" xml:lang="en-us">email</span></p>
<p class="MsoNormal"><span lang="en-us" xml:lang="en-us"><span>                            </span>if (/^[^@]+@[a-z0-9]+([_\.\-]{0,1}[a-z0-9]+)*([\.]{1}[a-z0-9]+)+$/.test(email)) {</span></p>
<p class="MsoNormal"><span lang="en-us" xml:lang="en-us"><span>                                     </span>// </span><span>把真正的</span><span lang="en-us" xml:lang="en-us">email</span><span>插入到页面中</span></p>
<p class="MsoNormal"><span lang="en-us" xml:lang="en-us"><span>                                     </span>link[e].href = "mailto:" + email;</span></p>
<p class="MsoNormal"><span lang="en-us" xml:lang="en-us"><span>                   </span><span>                   </span>link[e].firstChild.nodeValue = email;</span></p>
<p class="MsoNormal"><span lang="en-us" xml:lang="en-us"><span>                            </span>}</span></p>
<p class="MsoNormal"><span lang="en-us" xml:lang="en-us"><span>                   </span>}</span></p>
<p class="MsoNormal"><span lang="en-us" xml:lang="en-us"><span>         </span>}</span></p>
<p class="MsoNormal"><span lang="en-us" xml:lang="en-us">}</span></p>
<p class="MsoNormal"><span lang="en-us" xml:lang="en-us">&lt;/script&gt;</span></p>
<p class="MsoNormal"><span lang="en-us" xml:lang="en-us"><br /></span><span>最后，我们需要确保在网页加载完毕后运行</span><span lang="en-us" xml:lang="en-us">email.js</span><span>：</span><span lang="en-us" xml:lang="en-us"><br /> window.onload = EmailUnobsfuscate;</span></p>
<p class="MsoNormal"><span lang="en-us" xml:lang="en-us"> </span></p>
<p class="MsoNormal" align="left"><span>使用两者结合的结果是：</span></p>
<p class="MsoNormal" align="left"><span lang="en-us" xml:lang="en-us"><span>n<span>          </span></span></span><span>我们的原始<span lang="en-us" xml:lang="en-us">HTML</span>网页中没有<span lang="en-us" xml:lang="en-us">”<a href="mailto:">mailto:</a>”</span>链接，同时也不会轻易收到垃圾邮件发送者发来的垃圾邮件。</span></p>
<p class="MsoNormal" align="left"><span lang="en-us" xml:lang="en-us"><span>n<span>          </span></span></span><span>绝大多数的用户（那些启用<span lang="en-us" xml:lang="en-us">JavaScript </span>）将看到一个标准的电子邮件地址和<span lang="en-us" xml:lang="en-us">“<a href="mailto:">mailto:</a>”</span>链接。</span></p>
<p class="MsoNormal" align="left"><span lang="en-us" xml:lang="en-us"><span>n<span>          </span></span></span><span>少部分禁用脚本的用户可以看到<span lang="en-us" xml:lang="en-us">“</span></span><span lang="en-us" xml:lang="en-us">bob (at) bobsdomain dot com</span><span lang="en-us" xml:lang="en-us">”</span><span>的地址。</span></p>
<p class="MsoNormal" align="left"><span>说了这么多，意图就是展示这些概念，而不是这些代码。尽管例子能正常工作，但我还是建议你：</span></p>
<p class="MsoNormal" align="left"><span lang="en-us" xml:lang="en-us"><span>n<span>          </span></span></span><span>使用您自己的伪装电子邮件格式，例如：<span lang="en-us" xml:lang="en-us"> “</span></span><span lang="en-us" xml:lang="en-us">bob {@} bobsdomain – dot - com</span><span lang="en-us" xml:lang="en-us">”</span><span>。因为垃圾邮件发送者可以阅读这篇文章后变换编码的电子邮件，然后轻易的对付你！</span></p>
<p class="MsoNormal" align="left"><span lang="en-us" xml:lang="en-us"><span>n<span>          </span></span></span><span>使用不同的链接标识符<span lang="en-us" xml:lang="en-us">--- “email”</span>有点明显！</span></p>
<p class="MsoNormal" align="left"><span lang="en-us" xml:lang="en-us"><span>n<span>          </span></span></span><span>使用<span lang="en-us" xml:lang="en-us">JavaScript</span>库，例如<span lang="en-us" xml:lang="en-us">jQuery </span>，使代码更为简短。您还应该确保它应付空格或其他<span lang="en-us" xml:lang="en-us">DOM</span>节点周围的电子邮件地址文字（不处理的代码段） 。</span></p>
<p class="MsoNormal" align="left"><span lang="en-us" xml:lang="en-us"><span>n<span>          </span></span></span><span>使用一个更强大的事件处理程序来取代<span lang="en-us" xml:lang="en-us">window.onload</span>。</span></p>
<p class="MsoNormal" align="left"><span>祝您好运。 <span lang="en-us" xml:lang="en-us"><br /><br /></span></span></p>
<p class="MsoNormal" align="left"><span>例子演示<span lang="en-us" xml:lang="en-us">:http://www.cssrain.cn/demo/howtoemail.html</span></span></p>
<p><span>原文地址<span lang="en-us" xml:lang="en-us">:</span></span><span lang="en-us" xml:lang="en-us">http://www.sitepoint.com/blogs/2009/05/05/stop-spam-harvesting-email-obfuscation/<br /><br /></span></p><p><a href="http://www.yeeyan.com/articles/view/13127/44259#newComment">添加评论</a></p>
<p><embed id="movie_rss" height="60" width="468" quality="high" bgcolor="#ffffff" name="mymovie" style="" src="http://www.yeeyan.com/files/newindexads/vancl_090622_468_rss.swf" type="application/x-shockwave-flash"/></p>
]]>
        </content>
    <feedburner:origLink>http://www.yeeyan.com/articles/view/13127/44259</feedburner:origLink></entry>
    <entry>
        <title>VC10中的C&amp;#43;&amp;#43;0x特性 Part 2 &amp;#40;5&amp;#41; : 右值引用</title>
        <link href="http://feedproxy.google.com/~r/yeeyan_lang/~3/yPu-MOHXdfY/44050" />
        <created>2009-06-02T07:02:57+00:00</created>
        <issued>2009-06-02T07:02:57+00:00</issued>
        <modified>2009-06-02T07:02:57+00:00</modified>
        <published>2009-06-02T07:02:57+00:00</published>
        <id>tag:feed.yeeyan.com:translation/44050</id>
        <category term="电脑网络" scheme="feed.yeeyan.com" label="电脑网络" />
        <author>
            <name>飘飘白云</name>
            <uri>http://www.yeeyan.com/space/show/kesalin</uri>
        </author>
        <content type="html">
            <![CDATA[<p>原文作者：Visual C&#43;&#43; Team Blog<br />原文链接：<a href="http://blogs.msdn.com/vcblog/archive/2009/02/03/rvalue-references-c-0x-features-in-vc10-part-2.aspx">Rvalue References: C&#43;&#43;0x Features in VC10, Part 2（5）</a><br/>译者：<a href="http://www.yeeyan.com/space/show/kesalin">飘飘白云</a></p><p style="text-align:center;"><span style="font-size:medium;"><strong>VC10中的C++0x特性 Part 2 (5) : 右值引用</strong><br /></span></p>
<p style="text-align:center;"><span style="font-size:medium;">来源：<a title="vcvlog" href="http://blogs.msdn.com/vcblog/archive/2009/02/03/rvalue-references-c-0x-features-in-vc10-part-2.aspx" target="_blank">vcblog</a> 翻译：<a href="http://www.cppblog.com/kesalin" target="_blank">飘飘白云</a> kesalin@gmail.com<br /></span></p>
<p><span style="font-size:medium;">这个系列的第一部分（ <a href="http://www.yeeyan.com/articles/view/kesalin/43288" target="_blank">1</a>， <a href="http://www.yeeyan.com/articles/view/kesalin/43571" target="_blank">2</a>， <a href="http://www.yeeyan.com/articles/view/kesalin/43573" target="_blank">3</a> ）介绍了 <strong>lambda</strong>, <strong>auto </strong>和 <strong>static_assert</strong>。<br />第二部分共五页：</span><span style="font-size:medium;">  </span><span style="font-size:medium;"><a href="http://www.yeeyan.com/articles/view/kesalin/43500">第一页</a>  <a href="http://www.yeeyan.com/articles/view/kesalin/43772" target="_blank">第二页</a>  <a href="http://www.yeeyan.com/articles/view/kesalin/43774" target="_blank">第三页</a></span><span style="font-size:medium;">  <a href="http://www.yeeyan.com/articles/view/kesalin/44047" target="_self">第四页</a> <a href="http://www.yeeyan.com/articles/view/kesalin/44050" target="_self">本页</a><br /><br /></span><span style="font-size:medium;">现在，让我们来揭开“魔术“的神秘面纱，其实它靠的就是模板参数推导和引用折叠(reference collapsing)技术。<strong><br /><br />rvalue 引用：模板参数推导和引用折叠</strong><strong>(reference collapsing)<br /><br /></strong>rvalue 引用与模板以一种特别的方式相互作用。下面是一个示例：</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">C:\Temp&gt;type collapse.cpp</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">#include &lt;iostream&gt;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">#include &lt;ostream&gt;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">#include &lt;string&gt;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">using namespace std;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">template &lt;typename T&gt; struct Name;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">template &lt;&gt; struct Name&lt;string&gt; {</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    static const char * get() {</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">        return "string";</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    }</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">};</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">template &lt;&gt; struct Name&lt;const string&gt; {</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    static const char * get() {</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">        return "const string";</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    }</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">};</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">template &lt;&gt; struct Name&lt;string&amp;&gt; {</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    static const char * get() {</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">        return "string&amp;";</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    }</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">};</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">template &lt;&gt; struct Name&lt;const string&amp;&gt; {</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    static const char * get() {</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">        return "const string&amp;";</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    }</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">};</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">template &lt;&gt; struct Name&lt;string&amp;&amp;&gt; {</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    static const char * get() {</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">        return "string&amp;&amp;";</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    }</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">};</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">template &lt;&gt; struct Name&lt;const string&amp;&amp;&gt; {</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    static const char * get() {</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">        return "const string&amp;&amp;";</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    }</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">};</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">template &lt;typename T&gt; void quark(T&amp;&amp; t) {</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    cout &lt;&lt; "t: " &lt;&lt; t &lt;&lt; endl;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    cout &lt;&lt; "T: " &lt;&lt; Name&lt;T&gt;::get() &lt;&lt; endl;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    cout &lt;&lt; "T&amp;&amp;: " &lt;&lt; Name&lt;T&amp;&amp;&gt;::get() &lt;&lt; endl;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    cout &lt;&lt; endl;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">}</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">string strange() {</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    return "strange()";</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">}</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">const string charm() {</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    return "charm()";</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">}</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">int main() {</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    string up("up");</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    const string down("down");</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    quark(up);</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    quark(down);</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    quark(strange());</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    quark(charm());</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">}</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">C:\Temp&gt;cl /EHsc /nologo /W4 collapse.cpp</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">collapse.cpp</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">C:\Temp&gt;collapse</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">t: up</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">T: string&amp;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">T&amp;&amp;: string&amp;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">t: down</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">T: const string&amp;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">T&amp;&amp;: const string&amp;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">t: strange()</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">T: string</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">T&amp;&amp;: string&amp;&amp;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">t: charm()</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">T: const string</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">T&amp;&amp;: const string&amp;&amp;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Verdana;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">这里藉由 Name 的显式规格说明来打印出类型。</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><br /></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">当我们调用 quark(up) 时，会进行模板参数推导。 quark() 是一个带有模板参数 T 的模板函数，但是我们还没有为它提供显式的类型参数（比如像 quark&lt;X&gt;(up)这样的）。通过比较函数形参类型 Type&amp;&amp; 和函数实参类型（一个 string 类型的 lvalue）我们就能推导出</span><span style="font-size:medium;">模板实参类型</span><span style="font-size:medium;">。（译注：原文用 </span><span style="font-size:medium;">argument 表示实参，</span><span style="font-size:medium;">parameter 表示形参</span><span style="font-size:medium;">）</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><br /></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">C++0x 会转换函数实参</span><span style="font-size:medium;">的</span><span style="font-size:medium;">类型和形参</span><span style="font-size:medium;">的</span><span style="font-size:medium;">类型，然后再进行匹配。</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><br /></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">首先，转换函数实参的类型。这遵循一条<strong>特殊规则</strong>(提案N2798 14.8.2.1[temp.deduct.call]/3)：如果模板形参类型为 <strong>T</strong>，函数形参类型为 <strong>T&amp;&amp;</strong> ，且函数实参类型为 <strong>A</strong> 的 lvalue，那么模板实参类型会被推导为 <strong>A&amp; </strong>。（但这条特殊规则不适用于函数形参类型为 <strong>T&amp;</strong> 或 <strong>const T&amp;</strong> 的情况，这种情况下会和 C++98/03 保持一致，另外它也不适用于函数形参类型为 <strong>const T&amp;&amp;</strong> 的情况）。在 <strong>quark（up）</strong> 这个例子中，依照这个规则我们会把 <strong>string </strong>转换成 <strong>string&amp;</strong> 。</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><br /></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">然后，转换函数形参的类型。不管是 C++98/03 还是 C++0x 都会解除引用( lvalue 引用和 rvalue 引用在 C++0x 中都会被解除掉)。在前面例子的四种情形中，这样我们会把 <strong>T&amp;&amp;</strong> 转换成 <strong>T</strong> 。</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><br /></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">于是， <strong>T</strong> <strong>会被推导成函数实参转换之后的类型</strong>。<strong>up</strong> 和 <strong>down</strong> 都是 lvalue，它们遵循那条特殊规则，这就是为什么 <strong>quark(up)</strong><strong>  </strong>打印出<strong></strong>"<strong>T:string&amp;</strong>" ，而 <strong>quark(down)</strong> 打印出 "<strong>T: cosnt string&amp;</strong>"的原因。<strong>strange()</strong> 和 <strong>charm()</strong> 都是右值，它们遵循一般规则，这就是为什么 <strong>quark(strange())</strong> 打印出 "<strong>T: string</strong>" 而 <strong>quark(charm())</strong> 打印出"<strong>T: const string</strong>" 的原因。</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><br /></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">替换操作会在类型推导之后进行。模板形参 <strong>T</strong> 出现的</span><span style="font-size:medium;">每一个</span><span style="font-size:medium;">地方都会被替换成推导出来的模板实参类型。在 <strong>quark(string())</strong> 中 <strong>T</strong> 是 <strong>string </strong>，因此 <strong>T&amp;&amp;</strong> 会是 <strong>string&amp;&amp;</strong> 。同样，在 <strong>quark(charm())</strong> 中，<strong>T</strong> 是 <strong>const string</strong> ， 因此 <strong>T&amp;&amp;</strong> 是 <strong>const string&amp;&amp;</strong> 。但 quark(up) 和 quark(down) 不同，它们遵循另外的特殊规则。</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><br /></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">在 <strong>quark(up)</strong> 中， <strong>T</strong> 是 <strong>string&amp;</strong> 。进行替换的话 <strong>T&amp;&amp;</strong> 就成了 <strong>string&amp; &amp;&amp;</strong> ，在 C++0x 中会折叠（collapse）引用的引用，<strong>引用折叠的规则就是“lvalue 引用是传染性的”</strong>。 <strong>X&amp; &amp;</strong>, <strong>X&amp; &amp;&amp;</strong> 和 <strong>X&amp;&amp; &amp;</strong> 都会被折叠成 <strong>X&amp;</strong> ，只有 <strong>X&amp;&amp; &amp;&amp;</strong> 会被折叠成 <strong>X&amp;&amp;</strong> 。因此 <strong>string&amp; &amp;&amp;</strong> 被折叠成 <strong>string&amp;</strong> 。在模板世界里，那些看起来像 rvalue 引用的东西并不一定真的就是。 因而 <strong>quark(up)</strong> 被实例化为 <strong>quark&lt;string&amp;&gt;()</strong> ，进而 <strong>T&amp;&amp;</strong> 经替换与折叠之后变成 <strong>string&amp;</strong> 。我们可以调用 <strong>Name&lt;T&amp;&amp;&gt;::get()</strong> 来验证这个。 同样， <strong>quark(down)</strong> 被实例化为 <strong>quark&lt;const string&amp;&gt;()</strong> ，进而 <strong>T&amp;&amp;</strong> 经替换与折叠之后变成 <strong>const string&amp;</strong> 。在 C++98/03中，你可能习惯了常量性(constness)隐藏于模板形参中(也就是说可以传 <strong>const Foo</strong> 对象作实参来调用形参为 <strong>T&amp;</strong> 的模板函数，就像 <strong>T&amp;</strong> 会是 <strong>const Foo&amp;</strong> 一样)，在 C++0x 中，左值属性(lvalueness) 也能隐藏于模板形参中。</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><br /></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">那好，这两条特殊规则对我们有什么影响？在 quark() 内部，类型 <strong>T&amp;&amp;</strong> 有着和传给 <strong>quark() </strong>的实参一样的左/右值属性(lvalueness/rvalueness)和常量性。这样 <strong>rvalue 引用就能保持住左右值属性和常量性，做到完美转发。</strong><br /></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><br /><strong>完美转发： std::forward() 和 std::identidy 是怎样工作的</strong></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><br />让我们再来看看 outer() :<br /></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><br /></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">template &lt;typename T1, typename T2&gt; void outer(T1&amp;&amp; t1, T2&amp;&amp; t2) {</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    inner(<strong>Forward&lt;T1&gt;(</strong>t1<strong>)</strong>, <strong>Forward&lt;T2&gt;(</strong>t2<strong>)</strong>);</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">}</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><br />现在我们明白了为什么<strong> outer()</strong> 的形参是 <strong>T1&amp;&amp;</strong> 和 <strong>T2&amp;&amp;</strong> 类型的了，因为它们能够保持住传给 <strong>outer()</strong> 的实参的信息。那为什么这里要调用 <strong>Forward&lt;T1&gt;()</strong> 和 <strong>Forward&lt;T2&gt;()</strong> 呢？还记得么，具名 lvalue 引用和具名 rvalue 引用都是 lvalue 。如果 <strong>outer()</strong> 调用 <strong>inner(t1, t2)</strong> ，那么 <strong>inner()</strong> 总是会当 lvalue 来引用 <strong>t1</strong> 和 <strong>t2</strong> ，这就破坏了完美转发。</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><br /></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">幸运的是，不具名 lvalue 引用是 lvalue，不具名 rvalue 引用还是 rvalue 。因此，为了将 t1 和 t2 转发给 inner()，我们需要将它们传到一个帮助函数中去，这个帮助函数移除它们的名字，保持住它们的属性信息。这就是 std::forward() 做的事情：</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><br /></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">template &lt;typename T&gt; struct Identity {</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    typedef T type;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">};</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><br /></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">template &lt;typename T&gt; T&amp;&amp; Forward(typename Identity&lt;T&gt;::type&amp;&amp; t) {</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    return t;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">}</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><br />当我们调用 <strong>Forward&lt;T1&gt;(t1)</strong> ， <strong>Identidy</strong> 并没有修改 <strong>T1</strong> （很快我们讲到 <strong>Identidy</strong> 对 <strong>T1</strong> 做了什么）。因此 <strong>Forward&lt;T1&gt;()</strong> 接收 <strong>T1&amp;&amp;</strong> ，返回 <strong>T1&amp;&amp;</strong> 。这样就</span><span style="font-size:medium;">移除了 <strong>t1</strong> 的名字，</span><span style="font-size:medium;">保持住 <strong>t1</strong> 的类型信息（而不论 <strong>t1</strong> 是什么类型， string&amp; 也好, const string&amp; 也好, string&amp;&amp; 也好或 const string&amp;&amp; 也好）。这样 <strong>inner()</strong> 看到的 <strong>Forward&lt;T1&gt;(t1)</strong> ，与 <strong>outer()</strong> 接收的第一个实参有着相同的信息，包括类型，lvalueness/rvalueness，常量性等等。完美转发就是这样工作的。</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><br /></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">你可能会好奇如果不小心写成 <strong>Forward&lt;T1&amp;&amp;&gt;(t1) </strong>又会怎样呢？（这个错误还是蛮诱人的，因为 <strong>outer() </strong>接收的就是 <strong>T1&amp;&amp; t1</strong> ）。很幸运，没什么坏事情会发生。 <strong>Forward&lt;T1&amp;&amp;&gt;()</strong> 接收与返回的都是 <strong>T1&amp;&amp; &amp;&amp;</strong> ，这会被折叠成 <strong>T1&amp;&amp;</strong> 。于是，<strong>Forward&lt;T1&gt;(t1)</strong> 和 <strong>Forward&lt;T1&amp;&amp;&gt;(t1)</strong> 是等价的，我们更偏好前者，是因为它要短些。</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><br /></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><strong>Identidy</strong> 是做什么用的呢？为什么下面的代码不能工作？</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><br /></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">template &lt;typename T&gt; T&amp;&amp; Forward(<strong>T&amp;&amp; t</strong>) { <strong>// BROKEN</strong></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    return t;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">}</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><br /></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">如果 <strong>Forward()</strong> 像是上面那样，它就能被隐式调用（不带明确的模板参数）。当我们传给<strong> Forward()</strong> 一个 lvalue 实参时，模板参数推导就介入了，如我们前面看到的那样会将 <strong>T&amp;&amp;</strong> 变成 <strong>T&amp;</strong>，也就是变成一个 lvalue 引用。问题来了，即使形参 <strong>T1&amp;&amp;</strong> 和 <strong>T2&amp;&amp;</strong> 指明是 rvalue 引用，但在 <strong>outer()</strong> 中，具名的 <strong>t1</strong> 和 <strong>t2</strong> 却是 lvaue ，这个问题是我们一直想要解决的！使用上面那个错误的实现， <strong>Forward&lt;T1&gt;(t1)</strong> 是可以工作的，而 <strong>Foarward(t1)</strong> 虽然能通过编译（很诱人哦）但会出错，就如它就是 <strong>t1</strong> 一样。真是痛苦的源泉啊，因此，<strong>Identity</strong> <strong>被用来阻止模板参数推导</strong>。<strong>typename Identity&lt;T&gt;::type</strong> 中的那对冒号就像绝缘体，模板参数推导无法穿越它，有模板编程经验的程序员应该对此很熟悉了，因为这在 C++98/03 和 C++0x 中是一样的。（要解释这个是另外的事情了）</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><br /></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><strong>move 语意： std::move() 是怎样工作的</strong></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><br /></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">现在我们已经学习了模板参数推导和引用折叠的特殊规则，让我们再来看看 std::move() :</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><br /></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">template &lt;typename T&gt; struct RemoveReference {</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">     typedef T type;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">};</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">template &lt;typename T&gt; struct RemoveReference&lt;T&amp;&gt; {</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">     typedef T type;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">};</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">template &lt;typename T&gt; struct RemoveReference&lt;T&amp;&amp;&gt; {</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">     typedef T type;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">};</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">template &lt;typename T&gt; typename RemoveReference&lt;T&gt;::type&amp;&amp; Move(T&amp;&amp; t) {</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    return t;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">}</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><br /><strong>RemoveReference </strong>机制基本上是复制 C++0x &lt;type_traits&gt; 中的 <strong>std::remove_reference</strong> 。举例来说，<strong>RemoveReference&lt;string&gt;::type</strong> , <strong>RemoveReference&lt;string&amp;&gt;::type</strong> 和 <strong>RemoveReference&lt;string&amp;&amp;&gt;::type</strong> 都是 <strong>string </strong>。</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><br /></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">同样， <strong>move()</strong> 机制也基本上是复制 C++0x &lt;utility&gt; 中的 <strong>std::move()</strong>。 <br /><br /></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><span>· 当调用 <strong>Move(string)</strong>, <strong>string </strong>是一个 lvalue 时， <strong>T</strong> 会被推导为 <strong>string&amp;</strong> ，于是<strong> Move()</strong> 接收的就是 <strong>string&amp;</strong> (经折叠之后)并返回 <strong>string&amp;&amp;</strong> (经 <strong>RemoveReference </strong>之后)。</span></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><br /></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><span>· 当调用 <strong>Move(const string)</strong>, <strong>const</strong> <strong>string </strong>是一个 lvalue 时， <strong>T</strong> 会被推导为 <strong>const string&amp;</strong> ，于是 <strong>Move()</strong> 接收的就是 <strong>const string&amp;</strong></span></span><span style="font-size:medium;"><span><strong>&amp;</strong></span></span><span style="font-size:medium;"><span> (经折叠之后)并返回 <strong>const string&amp;&amp;</strong> (经 <strong>RemoveReference </strong>之后)。</span></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><br /></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><span>· 当调用 <strong>Move(string)</strong>, <strong>string </strong>是一个 rvalue 时， <strong>T</strong> 会被推导为 <strong>string</strong> ，于是<strong> Move()</strong> 接收的就是 <strong>string</strong></span></span><span style="font-size:medium;"><span><strong>&amp;</strong></span></span><span style="font-size:medium;"><span><strong>&amp;</strong> 并返回 <strong>string&amp;&amp;</strong> 。</span></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><br /></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><span>· 当调用 <strong>Move(const string)</strong>, <strong>const</strong> <strong>string </strong>是一个 rvalue 时， <strong>T</strong> 会被推导为 <strong>const string</strong> ，于是 <strong>Move()</strong> 接收的就是 <strong>const string&amp;</strong></span></span><span style="font-size:medium;"><span><strong>&amp;</strong></span></span><span style="font-size:medium;"><span> 并返回 <strong>const string&amp;&amp;</strong> 。</span></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><br /></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">这就是 Move() 如何保持其参数的类型和常量性，还能把 lvalue 转换成 rvalue 的过程。</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><br /></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><strong>回顾</strong><br /><br />如果你想对 rvalue 引用有</span><span style="font-size:medium;">更多</span><span style="font-size:medium;">了解，你可以去读有关它们的提案。要注意，提案与现在的决定可能已经不同了， rvalue 引用已经被整合到 C++0x 草案中来了，在那里它得到持续的改进。有些提案或已不再正确，或已过时，或已有了替代方案，就没有被采纳。无论怎样，它们还是能提供一些有用信息的。</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><br /></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2002/n1377.htm">N1377</a></span><span style="font-size:medium;font-family:Verdana;">, </span><span style="font-size:medium;"><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2002/n1385.htm">N1385</a></span><span style="font-size:medium;font-family:Verdana;">, 和 </span><span style="font-size:medium;"><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2004/n1690.html">N1690</a></span><span style="font-size:medium;font-family:Verdana;"> 是主要的提案，</span><span style="font-size:medium;"><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2118.html">N2118</a></span><span style="font-size:medium;font-family:Verdana;"> 包含被整合进标准草案之前的最后版本。 </span><span style="font-size:medium;"><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1784.htm">N1784</a></span><span style="font-size:medium;font-family:Verdana;">, </span><span style="font-size:medium;"><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1821.htm">N1821</a></span><span style="font-size:medium;font-family:Verdana;">, </span><span style="font-size:medium;"><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2377.htm">N2377</a></span><span style="font-size:medium;font-family:Verdana;">, 和 </span><span style="font-size:medium;"><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2439.htm">N2439</a></span><span style="font-size:medium;font-family:Verdana;"> 记录了“将 Move 语意扩展到 *this ”的演化过程，这个也被整合到 C++0x 中来了，但还没有在VC10 中得到实现。</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><br /></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><strong>展望</strong></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><br /></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><a href="http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2008/n2812.html">N2812</a></span><span style="font-size:medium;"> “Rvalue 引用的安全问题（以及如何解决）” 提出了对初始化规则的修改，它禁止 rvalue 引用绑定到 lvalue 。 这不会影响 move 语意和完美转发，所以它不会让你刚学到的新技术失效（它只是修改了 std::move() 和 std::forward() 的实现）。</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><br /></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><span lang="en" xml:lang="en">Stephan T. Lavavej</span></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><span lang="en" xml:lang="en">Visual C++ Libraries Developer</span></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">Published Tuesday, February 03, 2009 9:27 AM 			by 			<a href="http://blogs.msdn.com/user/Profile.aspx?UserID=33825">vcblog</a></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><br /></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;text-align:center;"><span style="font-size:medium;">&lt; <a href="http://www.yeeyan.com/articles/view/kesalin/43500">第一页</a>  <a href="http://www.yeeyan.com/articles/view/kesalin/43772" target="_blank">第二页</a>  <a href="http://www.yeeyan.com/articles/view/kesalin/43774" target="_blank">第三页</a>  <a href="http://www.yeeyan.com/articles/view/kesalin/44047" target="_self">第四页</a> <a href="http://www.yeeyan.com/articles/view/kesalin/44050" target="_self">本页</a> &gt;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><br /></span></p><p><a href="http://www.yeeyan.com/articles/view/kesalin/44050#newComment">添加评论</a></p>
<p><embed id="movie_rss" height="60" width="468" quality="high" bgcolor="#ffffff" name="mymovie" style="" src="http://www.yeeyan.com/files/newindexads/vancl_090622_468_rss.swf" type="application/x-shockwave-flash"/></p>
]]>
        </content>
    <feedburner:origLink>http://www.yeeyan.com/articles/view/kesalin/44050</feedburner:origLink></entry>
    <entry>
        <title>VC10中的C&amp;#43;&amp;#43;0x特性 Part 2 &amp;#40;3&amp;#41; : 右值引用</title>
        <link href="http://feedproxy.google.com/~r/yeeyan_lang/~3/g9sbvvalfqY/43774" />
        <created>2009-06-01T06:44:18+00:00</created>
        <issued>2009-06-01T06:44:18+00:00</issued>
        <modified>2009-06-01T06:44:18+00:00</modified>
        <published>2009-06-01T06:44:18+00:00</published>
        <id>tag:feed.yeeyan.com:translation/43774</id>
        <category term="电脑网络" scheme="feed.yeeyan.com" label="电脑网络" />
        <author>
            <name>飘飘白云</name>
            <uri>http://www.yeeyan.com/space/show/kesalin</uri>
        </author>
        <content type="html">
            <![CDATA[<p>原文作者：Visual C&#43;&#43; Team Blog<br />原文链接：<a href="http://blogs.msdn.com/vcblog/archive/2009/02/03/rvalue-references-c-0x-features-in-vc10-part-2.aspx">Rvalue References: C&#43;&#43;0x Features in VC10, Part 2（3）</a><br/>译者：<a href="http://www.yeeyan.com/space/show/kesalin">飘飘白云</a></p><p style="text-align:center;"><strong><span style="font-size:medium;">VC10中的C++0x特性 Part 2 (3) : </span></strong><span style="font-size:medium;"><strong>右值引用</strong><br /></span></p>
<p style="text-align:center;"><span style="font-size:medium;">来源：<a title="vcvlog" href="http://blogs.msdn.com/vcblog/archive/2009/02/03/rvalue-references-c-0x-features-in-vc10-part-2.aspx" target="_blank">vcblog</a> 翻译：<a href="http://www.cppblog.com/kesalin" target="_blank">飘飘白云</a> kesalin@gmail.com</span></p>
<p><span style="font-size:medium;">这个系列的第一部分（ <a href="http://www.yeeyan.com/articles/view/kesalin/43288" target="_blank">1</a>， <a href="http://www.yeeyan.com/articles/view/kesalin/43571" target="_blank">2</a>， <a href="http://www.yeeyan.com/articles/view/kesalin/43573" target="_blank">3</a> ）介绍了 <strong>lambda</strong>, <strong>auto </strong>和 <strong>static_assert</strong>。</span></p>
<p><span style="font-size:medium;">第二部分共五页：</span>  <span style="font-size:medium;"><a href="http://www.yeeyan.com/articles/view/kesalin/43500">第一页</a>  <a href="http://www.yeeyan.com/articles/view/kesalin/43772" target="_blank">第二页</a>  <a href="http://www.yeeyan.com/articles/view/kesalin/43774" target="_blank">本页</a></span><span style="font-size:medium;"> <a target="_self">第四页</a> <a target="_self">第五页</a><br /></span></p>
<p> </p>
<p><strong><span style="font-size:medium;">move </span><span style="font-size:medium;">语意</span><span style="font-size:medium;">：从 lvalue 移动</span></strong></p>
<p><span style="font-size:medium;">现在，如果你喜欢用拷贝赋值函数来实现你的拷贝构造函数该怎样做呢，那你也可能试图用 move 拷贝赋值函数来实现 move 构造函数。这样作是可以的，但是你得小心。下面就是一个错误的实现：</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Verdana;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">C:\Temp&gt;type unified_wrong.cpp</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">#include &lt;stddef.h&gt;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">#include &lt;iostream&gt;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">#include &lt;ostream&gt;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">using namespace std;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">class remote_integer {</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">public:</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">    remote_integer() {</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">        cout &lt;&lt; "Default constructor." &lt;&lt; endl;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">        m_p = NULL;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">    }</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">    explicit remote_integer(const int n) {</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">        cout &lt;&lt; "Unary constructor." &lt;&lt; endl;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">        m_p = new int(n);</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">    }</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">    remote_integer(const remote_integer&amp; other) {</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">        cout &lt;&lt; "Copy constructor." &lt;&lt; endl;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">        m_p = NULL;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">        *this = other;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">    }</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">#ifdef MOVABLE</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">    remote_integer(remote_integer&amp;&amp; other) {</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">        cout &lt;&lt; "MOVE CONSTRUCTOR." &lt;&lt; endl;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">        m_p = NULL;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">        <strong>*this = other; // WRONG</strong></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">    }</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">#endif // #ifdef MOVABLE</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">    remote_integer&amp; operator=(const remote_integer&amp; other) {</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">        cout &lt;&lt; "Copy assignment operator." &lt;&lt; endl;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">        if (this != &amp;other) {</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">            delete m_p;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">            if (other.m_p) {</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">                m_p = new int(*other.m_p);</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">            } else {</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">                m_p = NULL;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">            }</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">        }</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">        return *this;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">    }</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">#ifdef MOVABLE</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">    remote_integer&amp; operator=(remote_integer&amp;&amp; other) {</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">        cout &lt;&lt; "MOVE ASSIGNMENT OPERATOR." &lt;&lt; endl;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">        if (this != &amp;other) {</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">            delete m_p;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">            m_p = other.m_p;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">            other.m_p = NULL;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">        }</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">        return *this;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">    }</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">#endif // #ifdef MOVABLE</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">    ~remote_integer() {</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">        cout &lt;&lt; "Destructor." &lt;&lt; endl;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">        delete m_p;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">    }</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">    int get() const {</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">        return m_p ? *m_p : 0;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">    }</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">private:</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">    int * m_p;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">};</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">remote_integer frumple(const int n) {</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">    if (n == 1729) {</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">        return remote_integer(1729);</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">    }</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">    remote_integer ret(n * n);</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">    return ret;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">}</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">int main() {</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">    remote_integer x = frumple(5);</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">    cout &lt;&lt; x.get() &lt;&lt; endl;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">    remote_integer y = frumple(1729);</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">    cout &lt;&lt; y.get() &lt;&lt; endl;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">}</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">C:\Temp&gt;cl /EHsc /nologo /W4 /O2 unified_wrong.cpp</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">unified_wrong.cpp</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">C:\Temp&gt;unified_wrong</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">Unary constructor.</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">Copy constructor.</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">Copy assignment operator.</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">Destructor.</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">25</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">Unary constructor.</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">1729</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">Destructor.</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">Destructor.</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">C:\Temp&gt;cl /EHsc /nologo /W4 /O2 /DMOVABLE unified_wrong.cpp</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">unified_wrong.cpp</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">C:\Temp&gt;unified_wrong</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">Unary constructor.</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">MOVE CONSTRUCTOR.</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><strong>Copy assignment operator.</strong></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">Destructor.</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">25</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">Unary constructor.</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">1729</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">Destructor.</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">Destructor.</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Verdana;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">(编译器在这里进行了返回值优化(RVO)，但不是具名返回值优化(NRVO)。就像我之前提到的，有些拷贝构造函数被 RVO 或 NRVO 优化掉了，但编译器并不总是能够做这样的优化，这时</span><span style="font-size:medium;">剩余的</span><span style="font-size:medium;">就由 move 构造函数来优化。)</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><br /></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">move 构造函数中</span><span style="font-size:medium;">标记为 WRONG 的那一行，调用了拷贝赋值函数，编译能通过也能运行，但这违背了 move 构造函数的本意。（译注：因为那个拷贝赋值函数只是进行普通的拷贝赋值，而不是 move 赋值！）</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><br /></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">这是怎么回事呢？记住：在C++98/03中，具名 lvalue 引用是左值(给定语句 int&amp; r = *p; r 是 lvalue)，不具名 lvalue 引用还是左值(给定语句 vector&lt;int&gt; v(10, 1729)， v[0] 返回 int&amp;， 你可以对这个不具名 lvalue 引用取址)。但是 rvalue 引用就不一样了：</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><br /></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Symbol;"><span>· 具名 </span></span><span style="font-size:medium;">lvalue</span><span style="font-size:medium;font-family:Symbol;"><span> 引用是 </span></span><span style="font-size:medium;">lvalue</span><span style="font-size:medium;font-family:Symbol;"><span>。<br /></span></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Symbol;"><span>· 不具名</span></span><span style="font-size:medium;"> rvalue</span><span style="font-size:medium;font-family:Symbol;"><span> 引用是 </span></span><span style="font-size:medium;">rvalue</span><span style="font-size:medium;font-family:Symbol;"><span>。<br /></span></span></p>
<p><span style="font-size:medium;"><br /></span></p>
<p><span style="font-size:medium;">一个具名 rvalue 引用是</span><span style="font-size:medium;">一个</span><span style="font-size:medium;"> lvalue 是因为可以对它施加多重操作，重复使用。相反，如果它是</span><span style="font-size:medium;">一个</span><span style="font-size:medium;"> ravlue 的话，那么对它施加的第一个操作能够“窃取”它，而后续操作就没机会了。这里的“窃取”是说不会被察觉到，所以这是行不通的。另一方面，不具名 rvalue 引用不能被重复使用，所以它仍保持右值(rvalueness)语意。</span></p>
<p><span style="font-size:medium;"><br /></span></p>
<p><span style="font-size:medium;">如果你真的打算用 move 赋值函数来实现 move 构造函数，你需要从 lvalue move，就像是从 rvalue move 一样。C++0x &lt;utility&gt; 中的 std::move() 具备这样的能力，VC10将会有这个（实际上，开发版中</span><span style="font-size:medium;">已经有</span><span style="font-size:medium;">了），但VC10 TCP版还没有，所以我会教你从头做起：</span></p>
<p><span style="font-size:medium;"><br /></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">C:\Temp&gt;type unified_right.cpp</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">#include &lt;stddef.h&gt;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">#include &lt;iostream&gt;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">#include &lt;ostream&gt;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">using namespace std;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><strong>template &lt;typename T&gt; struct RemoveReference {</strong></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><strong>     typedef T type;</strong></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><strong>};</strong></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><strong> </strong></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><strong>template &lt;typename T&gt; struct RemoveReference&lt;T&amp;&gt; {</strong></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><strong>     typedef T type;</strong></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><strong>};</strong></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><strong> </strong></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><strong>template &lt;typename T&gt; struct RemoveReference&lt;T&amp;&amp;&gt; {</strong></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><strong>     typedef T type;</strong></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><strong>};</strong></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><strong> </strong></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><strong>template &lt;typename T&gt; typename RemoveReference&lt;T&gt;::type&amp;&amp; Move(T&amp;&amp; t) {</strong></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><strong>    return t;</strong></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><strong>}</strong></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">class remote_integer {</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">public:</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">    remote_integer() {</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">        cout &lt;&lt; "Default constructor." &lt;&lt; endl;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">        m_p = NULL;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">    }</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">    explicit remote_integer(const int n) {</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">        cout &lt;&lt; "Unary constructor." &lt;&lt; endl;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">        m_p = new int(n);</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">    }</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">    remote_integer(const remote_integer&amp; other) {</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">        cout &lt;&lt; "Copy constructor." &lt;&lt; endl;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">        m_p = NULL;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">        *this = other;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">    }</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">#ifdef MOVABLE</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">    remote_integer(remote_integer&amp;&amp; other) {</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">        cout &lt;&lt; "MOVE CONSTRUCTOR." &lt;&lt; endl;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">        m_p = NULL;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><strong>        *this = Move(other); // RIGHT</strong></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">    }</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">#endif // #ifdef MOVABLE</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">    remote_integer&amp; operator=(const remote_integer&amp; other) {</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">        cout &lt;&lt; "Copy assignment operator." &lt;&lt; endl;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">        if (this != &amp;other) {</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">            delete m_p;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">            if (other.m_p) {</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">                m_p = new int(*other.m_p);</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">            } else {</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">                m_p = NULL;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">            }</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">        }</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">        return *this;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">    }</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">#ifdef MOVABLE</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">    remote_integer&amp; operator=(remote_integer&amp;&amp; other) {</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">        cout &lt;&lt; "MOVE ASSIGNMENT OPERATOR." &lt;&lt; endl;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">        if (this != &amp;other) {</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">            delete m_p;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">            m_p = other.m_p;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">            other.m_p = NULL;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">        }</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">        return *this;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">    }</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">#endif // #ifdef MOVABLE</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">    ~remote_integer() {</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">        cout &lt;&lt; "Destructor." &lt;&lt; endl;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">        delete m_p;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">    }</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">    int get() const {</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">        return m_p ? *m_p : 0;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">    }</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">private:</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">    int * m_p;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">};</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">remote_integer frumple(const int n) {</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">    if (n == 1729) {</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">        return remote_integer(1729);</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">    }</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">    remote_integer ret(n * n);</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">    return ret;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">}</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">int main() {</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">    remote_integer x = frumple(5);</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">    cout &lt;&lt; x.get() &lt;&lt; endl;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">    remote_integer y = frumple(1729);</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">    cout &lt;&lt; y.get() &lt;&lt; endl;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">}</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">C:\Temp&gt;cl /EHsc /nologo /W4 /O2 /DMOVABLE unified_right.cpp</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">unified_right.cpp</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">C:\Temp&gt;unified_right</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">Unary constructor.</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">MOVE CONSTRUCTOR.</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><strong>MOVE ASSIGNMENT OPERATOR.</strong></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">Destructor.</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">25</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">Unary constructor.</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">1729</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">Destructor.</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">Destructor.</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Verdana;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">（我将交替提及 std::move() 和我自己的 Move()，因为它们的实现是等价的） std::move() 是怎样工作的呢？目前，我只能跟你说这是“魔法”。（后面会有完整的解释，并不复杂，但它与模板参数推导和</span><span style="font-size:medium;color:#000000;">引用折叠（reference collapsing，译注：引用的引用）</span><span style="font-size:medium;">有关，后面讲完美转发的时候我们还会遇到这两个东西）。我可以用一个具体的例子来略过“魔法”：给定一个 string 类型的左值，像前面重载决议例子中的 up ，std::move(up) 调用 string&amp;&amp; std::move(string&amp;)，这个函数返回一个不具名的 rvalue 引用，它是一个 rvalue。给定一个 string 类型的 rvalue，像前面重载决议例子中的 strange()， std::</span><span style="font-size:medium;">move</span><span style="font-size:medium;">(strange()) 调用 string&amp;&amp; std::move(string&amp;&amp;)，同样这个函数还是返回一个不具名的 rvalue，还是 rvalue。</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><br /></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">std::move() 除了让你能用 move 复制函数来实现 move 构造函数之外，还能在其他地方发挥作用。无论何时，只要你有一个左值，而它的值也不再重要了（例如，它将被销毁或被赋值），你就可以使用 std::move(你的左值表达式) 来使用 move 语意。</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"> </p>
<p class="MsoNormal" style="margin:0in 0in 0pt;text-align:center;"> &lt;<span style="font-size:medium;">  </span><span style="font-size:medium;"><a href="http://www.yeeyan.com/articles/view/kesalin/43500">第一页</a>  <a href="http://www.yeeyan.com/articles/view/kesalin/43772" target="_blank">第二页</a>  <a href="http://www.yeeyan.com/articles/view/kesalin/43774" target="_blank">本页</a></span><span style="font-size:medium;"> <a target="_self">第四页</a></span><span style="font-size:medium;"> <a target="_self">第五页</a></span><span style="font-size:medium;">&gt;</span></p>
<p> </p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"> </p>
<p> </p><p><a href="http://www.yeeyan.com/articles/view/kesalin/43774#newComment">添加评论</a></p>
<p><embed id="movie_rss" height="60" width="468" quality="high" bgcolor="#ffffff" name="mymovie" style="" src="http://www.yeeyan.com/files/newindexads/vancl_090622_468_rss.swf" type="application/x-shockwave-flash"/></p>
]]>
        </content>
    <feedburner:origLink>http://www.yeeyan.com/articles/view/kesalin/43774</feedburner:origLink></entry>
    <entry>
        <title>VC10中的C&amp;#43;&amp;#43;0x特性 Part 2 &amp;#40;2&amp;#41; : 右值引用</title>
        <link href="http://feedproxy.google.com/~r/yeeyan_lang/~3/73U9bkYVsOY/43772" />
        <created>2009-05-30T19:22:24+00:00</created>
        <issued>2009-05-30T19:22:24+00:00</issued>
        <modified>2009-05-30T19:22:24+00:00</modified>
        <published>2009-05-30T19:22:24+00:00</published>
        <id>tag:feed.yeeyan.com:translation/43772</id>
        <category term="电脑网络" scheme="feed.yeeyan.com" label="电脑网络" />
        <author>
            <name>飘飘白云</name>
            <uri>http://www.yeeyan.com/space/show/kesalin</uri>
        </author>
        <content type="html">
            <![CDATA[<p>原文作者：Visual C&#43;&#43; Team Blog<br />原文链接：<a href="http://blogs.msdn.com/vcblog/archive/2009/02/03/rvalue-references-c-0x-features-in-vc10-part-2.aspx">Rvalue References: C&#43;&#43;0x Features in VC10, Part 2（2）</a><br/>译者：<a href="http://www.yeeyan.com/space/show/kesalin">飘飘白云</a></p><p style="text-align:center;"><strong><span style="font-size:medium;">VC10中的C++0x特性 Part 2 (2) : </span></strong><span style="font-size:medium;"><strong>右值引用</strong><br /></span></p>
<p style="text-align:center;"><span style="font-size:medium;">来源：<a title="vcvlog" href="http://blogs.msdn.com/vcblog/archive/2009/02/03/rvalue-references-c-0x-features-in-vc10-part-2.aspx" target="_blank">vcblog</a> 翻译：<a href="http://www.cppblog.com/kesalin" target="_blank">飘飘白云</a> kesalin@gmail.com</span></p>
<p><span style="font-size:medium;">这个系列的第一部分（ <a href="http://www.yeeyan.com/articles/view/kesalin/43288" target="_blank">1</a>， <a href="http://www.yeeyan.com/articles/view/kesalin/43571" target="_blank">2</a>， <a href="http://www.yeeyan.com/articles/view/kesalin/43573" target="_blank">3</a> ）介绍了 <strong>lambda</strong>, <strong>auto </strong>和 <strong>static_assert</strong>。</span></p>
<p><span style="font-size:medium;">第二部分共四页：  </span><span style="font-size:medium;"><a href="http://www.yeeyan.com/articles/view/kesalin/43500">第一页</a>  <a href="http://www.yeeyan.com/articles/view/kesalin/43772" target="_blank">本页</a>  <a href="http://www.yeeyan.com/articles/view/kesalin/43774" target="_blank">第三页</a></span>  <span style="font-size:medium;">第四页  <a target="_self">第五页</a></span></p>
<p> </p>
<p><span style="font-size:medium;"><strong>rvalue 引用：重载决议</strong></span></p>
<p><span style="font-size:medium;">函数</span><span style="font-size:medium;">可根据非常量和常量 lvalue 引用参数的不同而重载</span><span style="font-size:medium;">，这一点你应该很熟悉了</span><span style="font-size:medium;">。在 C++0x 中，函数也可根据非常量和常量 rvalue 引用参数的不同而重载。如果给出这四种形式的</span><span style="font-size:medium;">重载</span><span style="font-size:medium;">一元函数，你不应为表达式能优先绑定到与之相对应的引用上而决议出相应的重载函数这一点感到惊奇：</span></p>
<p><span style="font-size:medium;"><br /></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">C:\Temp&gt;type four_overloads.cpp</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">#include &lt;iostream&gt;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">#include &lt;ostream&gt;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">#include &lt;string&gt;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">using namespace std;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">void <strong>meow(string&amp; s)</strong> {</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    cout &lt;&lt; "meow(string&amp;): " &lt;&lt; s &lt;&lt; endl;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">}</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">void <strong>meow(const string&amp; s)</strong> {</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    cout &lt;&lt; "meow(const string&amp;): " &lt;&lt; s &lt;&lt; endl;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">}</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">void <strong>meow(string&amp;&amp; s)</strong> {</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    cout &lt;&lt; "meow(string&amp;&amp;): " &lt;&lt; s &lt;&lt; endl;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">}</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">void <strong>meow(const string&amp;&amp; s)</strong> {</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    cout &lt;&lt; "meow(const string&amp;&amp;): " &lt;&lt; s &lt;&lt; endl;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">}</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">string strange() {</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    return "strange()";</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">}</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">const string charm() {</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    return "charm()";</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">}</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">int main() {</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    string up("up");</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    const string down("down");</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    meow(up);</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    meow(down);</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    meow(strange());</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    meow(charm());</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">}</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">C:\Temp&gt;cl /EHsc /nologo /W4 four_overloads.cpp</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">four_overloads.cpp</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">C:\Temp&gt;four_overloads</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">meow(string&amp;): up</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">meow(const string&amp;): down</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">meow(string&amp;&amp;): strange()</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">meow(const string&amp;&amp;): charm()</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Verdana;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">在实践中，全部重载 Type&amp; , const Type&amp; , Type&amp;&amp; , const Type&amp;&amp; 并不是很有用。只重载 const Type&amp; 和 Type&amp;&amp; 更有意思些:</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><br /></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">C:\Temp&gt;type two_overloads.cpp</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">#include &lt;iostream&gt;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">#include &lt;ostream&gt;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">#include &lt;string&gt;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">using namespace std;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">void <strong>purr(const string&amp; s)</strong> {</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    cout &lt;&lt; "purr(const string&amp;): " &lt;&lt; s &lt;&lt; endl;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">}</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">void <strong>purr(string&amp;&amp; s)</strong> {</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    cout &lt;&lt; "purr(string&amp;&amp;): " &lt;&lt; s &lt;&lt; endl;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">}</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">string strange() {</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    return "strange()";</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">}</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">const string charm() {</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    return "charm()";</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">}</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">int main() {</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    string up("up");</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    const string down("down");</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    purr(up);</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    purr(down);</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    purr(strange());</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    purr(charm());</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">}</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">C:\Temp&gt;cl /EHsc /nologo /W4 two_overloads.cpp</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">two_overloads.cpp</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">C:\Temp&gt;two_overloads</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">purr(const string&amp;): up</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">purr(const string&amp;): down</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">purr(string&amp;&amp;): strange()</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">purr(const string&amp;): charm()</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><br /></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">上面的重载决议是怎么作出的呢？下面是规则：</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><br /></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><span>（1） 初始化规则拥有否决权。<br /></span></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><span>（2） lvalue 最优先绑定到 lvalue 引用，rvalue </span><span>最</span><span>优先绑定到 rvalue 引用。<br /></span></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><span>（3） </span>非常量<span>表达式倾向于绑定到</span>非常量<span>引用上。<br /></span></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><br /></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">（我说的“否决权”是指：进行重载决议时初始化<span>规则</span>否决那些不可行(译注：不满足 const 正确性)的候选函数，这些函数阻止将表达式绑定到引用上） 让我们一条一条来看看这些规则是怎么运作的。</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><br /></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><span>·对 purr(up) 而言，决议（1）</span></span><span style="font-size:medium;"><span>初始化规则</span></span><span style="font-size:medium;"><span>既不否决 </span></span><span style="font-size:medium;">purr(const string&amp;) 也不否决 purr(string&amp;&amp;)</span><span style="font-size:medium;">。 up 是 lvalue，因此满足</span><span style="font-size:medium;"><span>决议（2）中的 </span><span>lvalue 最优先绑定到 lvalue 引用，即</span></span><span style="font-size:medium;"> purr(const string&amp;</span><span style="font-size:medium;">)</span><span style="font-size:medium;">。up 还是非常量，因此满足</span><span style="font-size:medium;"><span>决议（3）</span>非常量<span>表达式倾向于绑定到</span>非常量<span>引用上</span></span><span style="font-size:medium;">，即</span><span style="font-size:medium;">purr(string&amp;&amp;)。两者放一块决议时，</span><span style="font-size:medium;"><span>决议（2）</span></span><span style="font-size:medium;">胜出，选择 </span><span style="font-size:medium;">purr(const string&amp;)</span><span style="font-size:medium;">。</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><br /></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><span>·对 purr(down) 而言， </span><span>决议（1）</span></span><span style="font-size:medium;"><span>初始化</span><span>规则</span></span><span style="font-size:medium;"><span>基于 const 正确性否决掉 </span></span><span style="font-size:medium;">purr(string&amp;&amp;)，因此 </span><span style="font-size:medium;">purr(const string&amp;) 胜出。</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><br /></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Symbol;"><span>·对 purr(strange()) 而言，</span></span><span style="font-size:medium;"><span>决议（1）</span></span><span style="font-size:medium;"><span>初始化</span><span>规则</span></span><span style="font-size:medium;"><span>既不否决 </span></span><span style="font-size:medium;">purr(const string&amp;) 也不否决 purr(string&amp;&amp;)</span><span style="font-size:medium;">。strange() 是 rvalue， 因此</span><span style="font-size:medium;">满足</span><span style="font-size:medium;"><span>决议（2）</span></span><span style="font-size:medium;"> rvalue 最优先绑定到 rvalue 引用，即</span><span style="font-size:medium;"> purr(string&amp;&amp;)。</span><span style="font-size:medium;">strange() 还是非常量，</span><span style="font-size:medium;">因此满足</span><span style="font-size:medium;"><span>决议（3）</span>非常量<span>表达式倾向于绑定到</span>非常量<span>引用上</span></span><span style="font-size:medium;">，即</span><span style="font-size:medium;">purr(string&amp;&amp;)上。purr(string&amp;&amp;) 在这里两票胜出。</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><br /></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Symbol;"><span>·对 </span></span><span style="font-size:medium;">purr(charm()) 而言，</span><span style="font-size:medium;"><span>决议（1）</span></span><span style="font-size:medium;"><span>初始化</span><span>规则</span></span><span style="font-size:medium;"><span>基于 const 正确性否决掉 </span></span><span style="font-size:medium;">purr(string&amp;&amp;)，因此 </span><span style="font-size:medium;">purr(const string&amp;) 胜出。</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><br /></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">值得注意的是当你只</span><span style="font-size:medium;">重载了</span><span style="font-size:medium;">const Type&amp; 和 </span><span style="font-size:medium;">Type&amp;&amp; ，非常量 rvalue 绑定到 Type&amp;&amp;，而其它的都绑定到 const Type&amp;。因此，这一组重载用来实现 move 语义。</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><br /></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">重要说明：返回值的函数应当返回 Type（如 strange() ）而不是返回 const Type （如 charm()）。</span><span style="font-size:medium;">后者不会带来什么好处（阻止非常量成员函数调用），还会阻止 move 语意优化。</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><br /></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><strong><span style="font-size:medium;">move 语义：模式</span></strong></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><br /></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">下面是一个简单的类 remote_integer, 内部存储一个指向动态分配的 int 指针（“远程拥有权”）。你应该对这个类的默认构造函数，一元构造函数，拷贝构造函数，拷贝赋值函数和析构函数都很熟悉了。我给它增加了 move 构造函数和 move 赋值函数，它们被#ifdef MOVABLE 围起来了，这样我就可以演示在有和没有这两个函数的情况下会有什么差别，在真实的代码中是不会这么做的。</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><br /></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><br /></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">C:\Temp&gt;type remote.cpp</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">#include &lt;stddef.h&gt;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">#include &lt;iostream&gt;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">#include &lt;ostream&gt;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">using namespace std;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">class remote_integer {</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">public:</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    remote_integer() {</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">        cout &lt;&lt; "Default constructor." &lt;&lt; endl;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">        m_p = NULL;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    }</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    explicit remote_integer(const int n) {</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">        cout &lt;&lt; "Unary constructor." &lt;&lt; endl;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">        m_p = new int(n);</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    }</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    remote_integer(const remote_integer&amp; other) {</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">        cout &lt;&lt; "Copy constructor." &lt;&lt; endl;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">        if (other.m_p) {</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">            m_p = new int(*other.m_p);</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">        } else {</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">            m_p = NULL;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">        }</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    }</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">#ifdef MOVABLE</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><strong>    remote_integer(remote_integer&amp;&amp; other) {</strong></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><strong>        cout &lt;&lt; "MOVE CONSTRUCTOR." &lt;&lt; endl;</strong></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><strong> </strong></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><strong>        m_p = other.m_p;</strong></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><strong>        other.m_p = NULL;</strong></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><strong>    }</strong></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">#endif // #ifdef MOVABLE</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    remote_integer&amp; operator=(const remote_integer&amp; other) {</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">        cout &lt;&lt; "Copy assignment operator." &lt;&lt; endl;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">        if (this != &amp;other) {</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">            delete m_p;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">            if (other.m_p) {</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">                m_p = new int(*other.m_p);</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">            } else {</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">                m_p = NULL;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">            }</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">        }</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">        return *this;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    }</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">#ifdef MOVABLE</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><strong>    remote_integer&amp; operator=(remote_integer&amp;&amp; other) {</strong></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><strong>        cout &lt;&lt; "MOVE ASSIGNMENT OPERATOR." &lt;&lt; endl;</strong></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><strong> </strong></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><strong>        if (this != &amp;other) {</strong></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><strong>            delete m_p;</strong></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><strong> </strong></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><strong>            m_p = other.m_p;</strong></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><strong>            other.m_p = NULL;</strong></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><strong>        }</strong></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><strong> </strong></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><strong>        return *this;</strong></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><strong>    }</strong></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">#endif // #ifdef MOVABLE</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    ~remote_integer() {</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">        cout &lt;&lt; "Destructor." &lt;&lt; endl;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">        delete m_p;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    }</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    int get() const {</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">        return m_p ? *m_p : 0;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    }</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">private:</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    int * m_p;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">};</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">remote_integer square(const remote_integer&amp; r) {</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    const int i = r.get();</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    return remote_integer(i * i);</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">}</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">int main() {</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    remote_integer a(8);</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    cout &lt;&lt; a.get() &lt;&lt; endl;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    remote_integer b(10);</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    cout &lt;&lt; b.get() &lt;&lt; endl;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    b = square(a);</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    cout &lt;&lt; b.get() &lt;&lt; endl;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">}</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">C:\Temp&gt;cl /EHsc /nologo /W4 remote.cpp</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">remote.cpp</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">C:\Temp&gt;remote</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">Unary constructor.</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">8</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">Unary constructor.</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">10</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">Unary constructor.</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">Copy assignment operator.</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">Destructor.</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">64</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">Destructor.</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">Destructor.</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">C:\Temp&gt;cl /EHsc /nologo /W4 <strong>/DMOVABLE</strong> remote.cpp</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">remote.cpp</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">C:\Temp&gt;remote</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">Unary constructor.</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">8</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">Unary constructor.</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">10</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">Unary constructor.</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><strong>MOVE ASSIGNMENT OPERATOR.</strong></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">Destructor.</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">64</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">Destructor.</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">Destructor.</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><br /></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">这里有几点值得注意：</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><br /></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><span>·</span></span><span style="font-size:medium;">我们重载了</span><span style="font-size:medium;">拷贝构造函数和 move 构造函数，还重载了拷贝赋值函数和 move 赋值函数。在前面我们已经看到了当函数通过 const Type&amp; 和 Type&amp;&amp; 进行重载时，会有怎样的结果。当 move 语意可用时，b = square(a) 会自动选择调用 move 赋值函数。</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><br /></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><span>·</span>move 构造函数和 move 赋值函数只是简单的从 other 那里“窃取”内存，而不用动态分配内存。当“窃取”内存时，我们只是拷贝 other 的指针成员，然后再把它置为 null。于是当 other 被销毁时，析构函数什么也不做。</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><br /></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><span>·</span>拷贝赋值函数和 move 赋值函数都需要进行自我赋值检查，为何拷贝赋值函数需要进行自我赋值检查是广为人知的。这是因为像 int 这样的内建数据(POD)类型能够正确地自我赋值（如：x = x ），因此，用户自定义的数据类型理应也可以正确地自我赋值。自我赋值实际上在手写代码里面是不存在的，但是在类似 std::sort() 之类的算法中，却很常见。在 C++0x 中，像 std::sort() 之类的算法能够通过挪动而非拷贝元素来实现。在这里（move 赋值函数）也需要进行自我赋值检查。</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><br /></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">这时，你可能会想它们（ move 拷贝构造函数和 move 赋值函数）与编译器自动生成（标准中用词“隐式声明”）的默认拷贝构造函数和默认赋值函数有什么相互影响呢。</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><br /></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><span>·</span>永远不会自动生成 <span>m</span>ove 构造函数和 move 赋值函数。</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><span>·</span>用户声明的构造函数，拷贝构造函数和 move 构造函数会抑制住默认构造函数的自动生成。</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><span>·</span>用户声明的拷贝构造函数会抑制住默认拷贝构造函数的自动生成，但是用户声明的 move 构造函数做不到。</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><span>·</span>用户声明的拷贝赋值函数会抑制住默认拷贝赋值函数的自动生成，但是用户声明的 move 赋值函数做不到。</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><br /></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">基本上，除了声明 move 构造函数会抑制默认构造函数的自动生成以外，自动生成规则不影响 move 语义。</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;text-align:center;"> </p>
<p class="MsoNormal" style="margin:0in 0in 0pt;text-align:center;">&lt; <span style="font-size:medium;"><a href="http://www.yeeyan.com/articles/view/kesalin/43500">第一页</a>  <a href="http://www.yeeyan.com/articles/view/kesalin/43772" target="_blank">本页</a>  <a href="http://www.yeeyan.com/articles/view/kesalin/43774" target="_blank">第三页</a></span>  <a href="http://www.yeeyan.com/articles/view/kesalin/44047" target="_self"><span style="font-size:medium;">第四页</span></a>  <a target="_self"><span style="font-size:medium;">第五页</span></a> &gt;</p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"> </p><p><a href="http://www.yeeyan.com/articles/view/kesalin/43772#newComment">添加评论</a></p>
<p><embed id="movie_rss" height="60" width="468" quality="high" bgcolor="#ffffff" name="mymovie" style="" src="http://www.yeeyan.com/files/newindexads/vancl_090622_468_rss.swf" type="application/x-shockwave-flash"/></p>
]]>
        </content>
    <feedburner:origLink>http://www.yeeyan.com/articles/view/kesalin/43772</feedburner:origLink></entry>
    <entry>
        <title>VC10中的C&amp;#43;&amp;#43;0x特性 Part 2 &amp;#40;1&amp;#41; : 右值引用</title>
        <link href="http://feedproxy.google.com/~r/yeeyan_lang/~3/sHGREbz0p-o/43500" />
        <created>2009-05-30T02:23:12+00:00</created>
        <issued>2009-05-30T02:23:12+00:00</issued>
        <modified>2009-05-30T02:23:12+00:00</modified>
        <published>2009-05-30T02:23:12+00:00</published>
        <id>tag:feed.yeeyan.com:translation/43500</id>
        <category term="科学技术" scheme="feed.yeeyan.com" label="科学技术" />
        <author>
            <name>飘飘白云</name>
            <uri>http://www.yeeyan.com/space/show/kesalin</uri>
        </author>
        <content type="html">
            <![CDATA[<p>原文作者：Visual C&#43;&#43; Team Blog<br />原文链接：<a href="http://blogs.msdn.com/vcblog/archive/2009/02/03/rvalue-references-c-0x-features-in-vc10-part-2.aspx">Rvalue References: C&#43;&#43;0x Features in VC10, Part 2</a><br/>译者：<a href="http://www.yeeyan.com/space/show/kesalin">飘飘白云</a></p><p style="text-align:center;"><strong><span style="font-size:medium;">VC10中的C++0x特性 Part 2 (1) : </span></strong><span style="font-size:medium;"><strong>右值引用</strong><br /></span></p>
<p style="text-align:center;"><span style="font-size:medium;">来源：<a title="vcvlog" href="http://blogs.msdn.com/vcblog/archive/2009/02/03/rvalue-references-c-0x-features-in-vc10-part-2.aspx" target="_blank">vcblog</a> 翻译：<a href="http://www.cppblog.com/kesalin" target="_blank">飘飘白云</a> kesalin@gmail.com</span></p>
<p><span style="font-size:medium;">这个系列的第一部分（ <a href="http://www.yeeyan.com/articles/view/kesalin/43288" target="_blank">1</a>， <a href="http://www.yeeyan.com/articles/view/kesalin/43571" target="_blank">2</a>， <a href="http://www.yeeyan.com/articles/view/kesalin/43573" target="_blank">3</a> ）介绍了 <strong>lambda</strong>, <strong>auto </strong>和 <strong>static_assert</strong>。</span></p>
<p><span style="font-size:medium;">第二部分共四页： <a href="http://www.yeeyan.com/articles/view/kesalin/43500">本页</a>  <a href="http://www.yeeyan.com/articles/view/kesalin/43772" target="_blank">第二页</a>  <a href="http://www.yeeyan.com/articles/view/kesalin/43774" target="_blank">第三页</a></span>  <span style="font-size:medium;"><a target="_self">第四页</a>  <a target="_self">第五页</a><br /></span></p>
<p><span style="font-size:medium;"><br /></span></p>
<p><span style="font-size:medium;">今天我要讲的是 <strong>rvalue references</strong> （右值引用），它能实现两件不同的事情：<strong></strong>move 语意和完美转发。刚开始会觉得它们难以理解，因为需要区分 <strong>lvalues </strong>和 <strong>rvalues </strong>，而只有极少数 C++98/03 程序员对此非常熟悉。</span><span style="font-size:medium;">这篇文章会很长，因为我打算极其详尽地解释 <strong>rvalue references</strong> 的运作机制。</span></p>
<p><span style="font-size:medium;"><br /></span></p>
<p><span style="font-size:medium;">不用害怕，使用 <strong>ravlue references</strong> 是很容易的，比听起来要容易得多。要在你的代码中实现<strong> move semantics </strong> 或 <strong>perfect forwarding </strong>只需遵循简单的模式，后文我会对此作演示的。学习如何使用<strong> rvalue references </strong>是绝对值得的，因为 <strong>move semantics </strong>能带来巨大的性能提升，而 perfect forwarding 让高度泛型代码的编写变得非常容易。</span></p>
<p><span style="font-size:medium;"><br /></span></p>
<p><span style="font-size:medium;"><strong>C++ 98/03 中的 </strong><strong>lvalues 和 </strong><strong>rvalues</strong></span></p>
<p><span style="font-size:medium;">要理解C++ 0x中的 rvalue references，你得先理解 C++ 98/03 中的 lvalues 与 rvalues。</span></p>
<p><span style="font-size:medium;"><br /></span></p>
<p><span style="font-size:medium;">术语 “lvalues” 和 “rvalues” 是很容易被搞混的，因为它们的历史渊源也是混淆。（顺带一提，它们的发音是 ‘L values“ 和  ”R values“， 尽管它们</span><span style="font-size:medium;">都写成一个单词）。这两个概念起初来自 C，后来在 C++ 中被加以发挥。为节省时间，我跳过了有关它们的历史，比如为什么它们被称作　“lvalues”　和　“rvalues”，我将直接讲它们在 C++ 98/03 中是如何运作的。（好吧，这不是什么大秘密： “L” 代表 “left”，“R” </span><span style="font-size:medium;">代表</span><span style="font-size:medium;"> “right”。它们的含义一直在演化而名字却没变，现在已经“名”不副“实”了。与其帮你上一整堂历史课，不如</span><span style="font-size:medium;">随意地</span><span style="font-size:medium;">把它们当作像“上夸克”和“下夸克”之类的名字，也不会有什么损失。）</span></p>
<p><span style="font-size:medium;"><br /></span></p>
<p><span style="font-size:medium;">C++ 03 标准 3.10/1 节上说： “每一个表达式要么是一个 <strong>lvalue</strong>，要么就是一个 <strong>rvalue</strong>。” 应该谨记 lvalue </span><span style="font-size:medium;">跟</span><span style="font-size:medium;"> rvalue 是针对表达式而言的，而不是对象。</span></p>
<p><span style="font-size:medium;"><br /></span></p>
<p><span style="font-size:medium;">lvalue 是指</span><span style="font-size:medium;">那些</span><span style="font-size:medium;">单一表达式结束之后依然存在的持久对象。例如： <strong>obj，*ptr， prt[index]， ++x</strong> 都是 lvalue。</span></p>
<p><span style="font-size:medium;"><br /></span></p>
<p><span style="font-size:medium;">rvalue </span><span style="font-size:medium;">是指</span><span style="font-size:medium;">那些表达式结束时（在分号处）就不复存在了的临时对象。例如：</span><span style="font-size:medium;"><strong>1729 ， x + y ， std::string("meow")</strong> ， 和 <strong>x++</strong> 都是 rvalue。</span></p>
<p><span style="font-size:medium;"><br /></span></p>
<p><span style="font-size:medium;">注意 ++x 和 x++ 的区别。当我们写 int x = 0; 时， x 是一个 lvalue，因为它代表一个持久对象。 表达式 ++x 也是一个 lvalue，它修改了 x 的值，但还是代表原来那个持久对象。然而，表达式 x++ 却是一个 rvalue，它只是拷贝一份持久对象的初值，再修改持久对象的值，最后返回那份拷贝，那份拷贝是临时对象。 ++x 和 x++ 都递增了 x，但 ++x 返回持久对象本身，而 x++ 返回临时拷贝。这就是为什么 ++x 之所以是一个 lvalue，而 x++ 是一个 rvalue。<strong>lvalue 与 rvalue 之分不在于表达式做了什么，而在于表达式代表了什么（持久对象或临时产物）。</strong></span></p>
<p><span style="font-size:medium;"><br /></span></p>
<p><span style="font-size:medium;"><strong>另一个</strong></span><span style="font-size:medium;"><strong>培养判断一个表达式是不是 lvalue 的直觉感的方法就是自问一下“我能不能对表达式取址？”，如果能够，那就是一个 lvalue；如果不能，那就是</strong></span><span style="font-size:medium;"><strong>一个</strong></span><span style="font-size:medium;"><strong> rvalue。</strong>例如：</span><span style="font-size:medium;">&amp;obj , &amp;*ptr , &amp;ptr[index] , 和 &amp;++x 都是合法的（即使其中一些例子</span><span style="font-size:medium;">很蠢</span><span style="font-size:medium;">），而 </span><span style="font-size:medium;">&amp;1729 , &amp;(x + y) , &amp;std::string("meow") , 和 &amp;x++ 是不合法的。为什么这个方法凑效？因为取址操作要求它的“操作数必须是一个 lvalue”（见 C++ 03 5.3.1/2）。为什么要有那样的规定？因为对一个持久对象取址是没问题的，但对一个临时对象取址是极端危险的，因为临时对象很快就会被销毁（译注：就像你有一个指向某个对象的指针，那个对象被释放了，但你还在使用那个指针，鬼知道这时候指针指向的是什么</span><span style="font-size:medium;">东西</span><span style="font-size:medium;">）。</span></p>
<p><span style="font-size:medium;"><br /></span></p>
<p><span style="font-size:medium;">前面的例子不考虑操作符重载的情况，它只是普通的函数调用语义。“一个函数调用是一个 lvalue 当且仅当它返回一个引用”（见 C++ 03 5.2.2/10）。因此，给定语句 vercor&lt;int&gt; v(10, 1729); ， v[0] 是一个 lvalue，因为操作符 []() 返回 int&amp; (且 &amp;v[0] 是合法可用的)； 而给定语句 </span><span style="font-size:medium;">string s("foo");和 string t("bar");，s + t 是一个rvalue，因为操作符 +() 返回 string（而 &amp;(s + t) 也不合法）。</span></p>
<p><span style="font-size:medium;"><br /></span></p>
<p><span style="font-size:medium;">lvalue 和 rvalue 两者都有非常量（modifiable，</span><span style="font-size:medium;">也就是说non-const</span><span style="font-size:medium;">）与常量（const ）之分。举例来说：</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Verdana;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">string one("cute");</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">const string two("fluffy");</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">string three() { return "kittens"; }</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">const string four() { return "are an essential part of a healthy diet"; }</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">one;     // modifiable lvalue</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">two;     // const lvalue</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">three(); // modifiable rvalue</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">four();  // const rvalue</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Verdana;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">Type&amp; 可绑定到</span><span style="font-size:medium;">非常量</span><span style="font-size:medium;"> lvalue （可以用这个引用来读取</span><span style="font-size:medium;">和修改</span><span style="font-size:medium;">原来的值），但不能绑定到 const lvalue，因为那将违背 const 正确性；也不能把它绑定到</span><span style="font-size:medium;">非常量</span><span style="font-size:medium;"> rvalue，这样做极端危险，你用这个引用来修改临时对象，但临时对象早就不存在了，这将导致难以捕捉而令人讨厌的 bug，因此 C++ 明智地禁止这这么做。（我要补充一句：VC 有一个邪恶的扩展允许这么蛮干，但如果你</span><span style="font-size:medium;">编译的时候</span><span style="font-size:medium;">加上参数 /W4 ，编译器通常会提示警告"邪恶的扩展被激活了”）。也不能把它绑定到 const ravlue，因为那会是双倍的糟糕。（细心的读者应该注意到了我在这里并没有谈及模板参数推导）。</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><br /></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">const Type&amp; 可以绑定到： </span><span style="font-size:medium;">非常量</span><span style="font-size:medium;"> lvalues， const lvalues，</span><span style="font-size:medium;">非常量</span><span style="font-size:medium;"> rvalues 以及 const values。</span><span style="font-size:medium;">（然后你就可以用这个引用来观察它们）</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><br /></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">引用是具名的，因此一个绑定到 rvalue 的引用，它本身是一个 lvalue（没错！是 L）。（因为只有 const 引用可以绑定到 rvalue，所以它是一个 const lvalue）。这让人费解，（不弄清楚的话）到后面会更难以理解，因此我将进一步解释。给定函数 void observe(const string&amp; str)， 在 observe()'s 的实现中， str 是一个 const lvalue，在 observe() 返回之前可以对它取址并使用那个地址。</span><span style="font-size:medium;">这一点</span><span style="font-size:medium;">即使我们通过传一个 rvalue 参数来调用</span><span style="font-size:medium;"> observe()也是成立的 </span><span style="font-size:medium;">，就像上面的 three() 和 four()。也可以调用 observe("purr")，它构建一个临时 string 并将 str 绑定到那个临时 string。three() 和 foure() 的返回对象是不具名的，因此他们是 rvalue，但是在 observe()中，str 是具名的，所以它是一个 lvalue。正如前面我说的“ lvalue 跟 rvalue 是针对表达式而言的，而不是对象”。当然，因为 str 可以被绑定到一个很快会被销毁的临时对象，所以</span><span style="font-size:medium;">在 observe() 返回之后我们就不应该在任何地方保存</span><span style="font-size:medium;">这个临时对象的地址。</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><br /></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">你有没有</span><span style="font-size:medium;">对</span><span style="font-size:medium;">一个</span><span style="font-size:medium;">绑定到</span><span style="font-size:medium;"> rvalue 的 const 引用取址过么？当然，你有过！每当你写一个带自赋值检查的拷贝赋值操作符： Foo&amp; operator=(const Foo&amp; other), if( this != &amp;other) { copy struff;}； 或从一个临时变量来拷贝赋值，像： Foo make_foo(); Foo f; f = make_foo(); 的时候，你就做了这样的事情。</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><br /></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">这个时候，你可能会问“那么</span><span style="font-size:medium;">非常量</span><span style="font-size:medium;"> rvalues 跟 const rvalues 有什么不同呢？我不能将 Type&amp; 绑定到</span><span style="font-size:medium;">非常量</span><span style="font-size:medium;"> rvalue 上，</span><span style="font-size:medium;">也不能通过赋值等操作来修改 rvalue，那我真的可以修改它们？” 问的很好！在 C++ 98/03 中，这两者存在一些细微的差异： </span><span style="font-size:medium;">non-const</span><span style="font-size:medium;">rvalues</span><span style="font-size:medium;"> 可以</span><span style="font-size:medium;">调用 non-const 成员函数。 C++ 不希望你意外地修改临时对象，但直接在</span><span style="font-size:medium;">non-const</span><span style="font-size:medium;"> rvalues上调用 non-const 成员函数，这样做是很明显的，所以这是被允许的。在 C++ 0x中，答案有了显著的变化，它能用来实现 move 语意。</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><br /></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">恭喜！你已经具备了我所谓的“lvalue/rvalue 观”，这样你就能够一眼就判断出一个表达式到底是 lvalue 还是 rvalue。再加上你原来对 const 的认识，你就能完全理解为什么给定语句 void mutate(string&amp; ref) 以及前面的变量定义， mutate(one) 是合法的，而 mutate(two)， mutate(three())， mutate(four())， mutate("purr") 都是不合法的。如果你是 C++ 98/03 程序员，你已经可以分辨出这些调用中的哪些是合法的，哪些是不合法的；是你的“本能直觉”，而不是你的编译器，告诉你 mutate(three()) 是假冒的。你对 lvalue/rvalue 的新认识让你明确地理解为什么 three() 是一个 rvalue，也知道为什么</span><span style="font-size:medium;">非常量</span><span style="font-size:medium;">引用不能绑定到右值。知道这些有用么？对语言律师而言，有用，但对普通程序员来说并不见得。毕竟，你如果不理解关于 lvalues 和 rvalues 一切就要领悟这个还隔得远呢。但是重点来了：与 C++ 98/03 相比， C++ 0x 中的 lvalue 和 rvalue 有着更广泛更强劲的含义（尤其是判断表达式是否是 modifiable / const 的 lvalue/rvalue，并据此做些处理）。要有效地使用 C++ 0x，你也需具备对 lvalue/rvalue 的理解。现在万事具备，我们能继续前行了。</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><br /></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><strong>拷贝的问题</strong></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><br /></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">C++ 98/03 将</span><span style="font-size:medium;">不可思议的</span><span style="font-size:medium;">高度抽象和不可思议的高效执行结合到了一起，但有个问题：它过度滥用拷贝。对行为像 int 那样有着值语意的对象而言，</span><span style="font-size:medium;">源对象的拷贝是独立存在的，</span><span style="font-size:medium;">并不会影响源对象。值语</span><span style="font-size:medium;">意</span><span style="font-size:medium;">很好，除了在会导致冗余拷贝</span><span style="font-size:medium;">之外，</span><span style="font-size:medium;">像拷贝 strings，vectors 等重型对象那样的情况。（“重型”意味着“昂贵的拷贝开销”；有着100万个元素的 vector 是重型的）。返回值优化（RVO） 和命名返回值优化（NRVO） 在特定情况下可以优化掉拷贝构造操作，这有助于减缓问题的严重性，但是它们不能够消除所有冗余的拷贝。</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><br /></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">最最没有必要的拷贝是拷贝那些立马会被销毁的对象。你有过复印一份文件，并马上把原件扔掉的经历么（假定原件和复件是相同的）？那简直是浪费，你应该持有原件而不必费劲去复印。下面是被我称作“杀手级的示例”，来自标准委员会的例子(见提案 N1377)，假设你有一大堆 string </span><span style="font-size:medium;">像这样的</span><span style="font-size:medium;">：</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><br /></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">string s0("my mother told me that");</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">string s1("cute");</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">string s2("fluffy");</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">string s3("kittens");</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">string s4("are an essential part of a healthy diet");</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><br /></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">然后你想这样把它们串接起来：</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><br /></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">string dest = s0 + " " + s1 + " " + s2 + " " + s3 + " " + s4;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><br /></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">这样做的效率如何？（我们不用为这个特殊的例子而担忧，它的执行只要几微秒；我们担忧它的一般化情况，在语言层面上的情况）。</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Verdana;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">每次调用操作符 +() 就会返回一个临时 string。上面调用了 8 次操作符 +()，因而产生了 8 个临时 string。 每一个临时 string，在构造过程中分配动态内存，再拷贝所有已连接的字符，最后在析构过程中释放分配的动态内存。（你听说过短串优化技术么，为了避免动态内存的分配与释放，VC是这么干的，在这个被我精心挑选的有着合适长度的 s0 面前短串优化技术也无能为力，即使执行了这样的优化，也无法避免拷贝操作。如果你还听说过写时拷贝优化（Copy - On - Write），忘了它吧，在这里也不适用，并且在多线程环境下这种优化会恶化问题，因此标准库实现根本就不再做这个优化了）。</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"> </p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">事实上，因为每一个串接操作都会拷贝所有已经串接好的字符，所以那个复杂度是字符串长度的平方了。哎呀！这太浪费了！这点确实让 C++ 尴尬。事情怎么会搞成这样呢？有没有改善的办法？</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"> </p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">问题是这样的，</span><span style="font-size:medium;">operator+()接受两个参数，一个是 </span><span style="font-size:medium;">const string&amp;，另一个是 </span><span style="font-size:medium;">const string&amp; 或 </span><span style="font-size:medium;">const char * (还有其他重载版本，但在这里我们没有用到)，但 </span><span style="font-size:medium;">operator+() 无法分辨出你塞给它的是 lvalue 还是 rvalue 参数，所以它只好总是创建一个临时 string，并返回这个临时 string。 为什么这跟 vavlue/rvalue 有关系？</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"> </p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">当我们要计算 s0 + " " 的值时，很明显这里有必要创建一个新的临时 string。 s0 是一个 lvalue，它已经命名了一个持久对象，因此我们不能修改它。（有人注意到了！） 。如果要计算 (s0 + “ ”) + s1 的值，我们可以简单地将 s1 的内容追加到第一个临时 string 上，而不用创建第二个临时 string 再把第一个丢弃掉。这就是 move 语意背后的核心观念： 因为 s0 + " " 是一个 rvalue ，只有那个在整个程序中唯一能够觉察到临时对象存在的表达式可以引用临时对象。如果我们能检测到表达式是一个非常量 rvalue，我们就可以任意修改临时对象，而不会有人发现。 操作符 +() 本不应该修改它的参数，但如果其参数是</span><span style="font-size:medium;">非常量</span><span style="font-size:medium;"> rvalue，谁在乎？照这种方法，每次调用操作符 +() 都把字符追加到唯一的临时对象上，这样就彻底省掉了不必要的动态内存管理和冗余的拷贝操作，呈现出线性复杂度。耶！</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><br /></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">从技术上讲，在 C++ 0x 中，每次调用操作符 +() 还是会返回一个单独的临时 string。 然而，第二个临时 string （产生自 (s0 + “ ”) + s1 ）可以通过“窃取”第一个临时 string （产生自 s0 + " "  ）的内存而被构造出来，然后再把 s1 的内容追加到那块内存后面（这将会引发一个普通的重分配操作）。“窃取”是通过指针的操作实现的：第二个临时 string 会先拷贝</span><span style="font-size:medium;">第一个临时 string 的内部指针，</span><span style="font-size:medium;">然后再清空这个指针。第一个临时 string 最后被销毁（在分号那地方）时，它的指针已经置为 null 了，因此它的析构函数什么也不会做（译注：也就是说不会释放它的内存，这部分内存现在是第二个临时 string 在使用了）。</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><br /></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">通常，如果能够检测到</span><span style="font-size:medium;">非常量</span><span style="font-size:medium;"> rvalue，你就能够做些“资源窃取”的优化。如果</span><span style="font-size:medium;">非常量</span><span style="font-size:medium;"> rvalue 所引用的那些对象持有任何资源（如内存），你就能窃取它们的资源而不用拷贝它们，反正它们很快就会被销毁掉。通过窃取</span><span style="font-size:medium;">非常量</span><span style="font-size:medium;"> rvalue 持有的资源来构建或赋值的手法通常被称作 “moving”，可移动对象拥有 “move 语意”。</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><br /></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">在大多数情况下这相当有用，比如 vector 的重新分配。当一个 vector 需要更多空间（如 push_back() 时）和进行重分配操作时，它需要从旧的内存块中拷贝元素到新的内存块中去。这些拷贝构造调用的开销很大。(对 vector&lt;string&gt; 来说，需要拷贝每一个 string 元素，这涉及动态内存分配)。但是等一等！旧内存块中的那些元素很快会被销毁掉的呀，所以我们可以挪动这些元素，而不用拷贝它们。在这种情形下，旧内存块中的元素依然</span><span style="font-size:medium;">存在于</span><span style="font-size:medium;">内存中，用来访问它们的表达式，如 old_ptr[index]，还是 lvalue。在重分配过程中，我们想用</span><span style="font-size:medium;">非常量</span><span style="font-size:medium;"> rvalue 表达式来引用旧内存块中的元素。假定它们是</span><span style="font-size:medium;">非常量</span><span style="font-size:medium;"> rvalue，那我们就能够移动它们，从而省去拷贝构造开销。（说”我想假定这个 lvalue 是一个</span><span style="font-size:medium;">非常量</span><span style="font-size:medium;"> rvalue “等同于说”我知道这是一个 lvalue，它指向一个持久对象，但我不关心随后会对这个 lvalue 进行怎样的操作，或销毁它，或给它赋值，或进行任意操作。因此如果你能从它那里窃取资源的话，尽管行动吧”）</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><br /></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">C++0x 的 rvalue 引用概念给与我们检测</span><span style="font-size:medium;">非常量</span><span style="font-size:medium;"> rvalue 并从中窃取资源的能力，这让我能够实现 move 语意。rvalue 引用也让我们能够通过把 lvalue 伪装成</span><span style="font-size:medium;">非常量</span><span style="font-size:medium;"> rvalue 而随意触发 move 语</span><span style="font-size:medium;">意</span><span style="font-size:medium;">。现在，我们来看看 rvalue 引用是如何工作的！</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><br /></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><strong><span style="font-size:medium;">ravlue 引用：初始化</span></strong></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><br /></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">C++0x 引进了一种新的引用，ravlue 引用，其语法是 <strong>Type&amp;&amp;</strong> 和 <strong>const Type&amp;&amp;</strong>。目前 C++0x 草案 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2798.pdf">N2798</a></span><span style="font-size:medium;"> 8.3.2/2 上说：“用 &amp; 声明的引用类型被称作 lvalue 引用，而用 &amp;&amp; 声明的引用</span><span style="font-size:medium;">类型</span><span style="font-size:medium;">被称作</span><span style="font-size:medium;"> rvalue 引用。lvalue 引用与 rvalue 引用是截然不同的类型。除非特别注明，两者在语意上是相当的并且一般都被称作引用。”这意味着对 C++98/03 中引用</span><span style="font-size:medium;">(即现在的 lvalue 引用)</span><span style="font-size:medium;">的直觉印象可以延伸用于 rvalue 引用；你只需要学习这两者的不同之处。</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><br /></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">（说明：我选择把 Type&amp; 读作 “Type ref”，Type&amp;&amp; 读作 "Type ref ref"。它们的全称分别是 “lvalue reference to Type” 和 "rvalue reference to Type"，就像 “cosnt pointer to int” 被写成 “int * const”，而被读作 “int star const”一样。）</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><br /></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">两者有什么区别？与 lvalue 引用相比， rvalue 引用在初始化与重载决议时表现出不同的行为。两者的区别在于它们会优先绑定到什么东西上（初始化时）和什么东西会</span><span style="font-size:medium;">优先</span><span style="font-size:medium;">绑定到它们身上(重载决议时)。首先让我们来看看初始化：</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><br /></span></p>
<p class="MsoListParagraph" style="margin:0in 0in 0pt .5in;text-indent:-.25in;"><span style="font-size:medium;"><span>· 我们已经明白为何</span></span><span style="font-size:medium;">非常量</span><span style="font-size:medium;"><span> lvalue 引用( Type&amp; ) </span>只能<span>绑定到</span></span><span style="font-size:medium;">非常量</span><span style="font-size:medium;"><span> lvalue 上，而其他的一概不能</span><span>（如 const lvalues，</span></span><span style="font-size:medium;">非常量</span><span style="font-size:medium;"><span> rvalues，const rvalues）<br /></span></span></p>
<p class="MsoListParagraph" style="margin:0in 0in 0pt .5in;text-indent:-.25in;"><span style="font-size:medium;"><br /></span></p>
<p class="MsoListParagraph" style="margin:0in 0in 0pt .5in;text-indent:-.25in;"><span style="font-size:medium;"><span>· 我们已经明白为何 const lvalue </span><span>引用</span><span>( const Type&amp; ) </span>能<span>绑定到任何</span>东西<span>上。</span></span></p>
<p class="MsoListParagraph" style="margin:0in 0in 0pt .5in;text-indent:-.25in;"><span style="font-size:medium;"><br /></span></p>
<p class="MsoListParagraph" style="margin:0in 0in 0pt .5in;text-indent:-.25in;"><span style="font-size:medium;"><span>· </span></span><span style="font-size:medium;">非常量</span><span style="font-size:medium;"><span> rvalue ( Type&amp;&amp; ) </span>能够<span>绑定到</span></span><span style="font-size:medium;">非常量</span><span style="font-size:medium;"><span> lvalue 以及</span></span><span style="font-size:medium;">非常量</span><span style="font-size:medium;"><span> rvalue 上，而不能绑定到 const lvalues 和 const rvalues （这会违背 const 正确性）</span></span></p>
<p class="MsoListParagraph" style="margin:0in 0in 0pt .5in;text-indent:-.25in;"><span style="font-size:medium;"><br /></span></p>
<p class="MsoListParagraph" style="margin:0in 0in 0pt .5in;text-indent:-.25in;"><span style="font-size:medium;"><span>· const rvalue 引用</span><span>( const Type&amp;&amp; ) </span>能够<span>绑定到任何</span>东西<span>上。</span></span></p>
<p class="MsoListParagraph" style="margin:0in 0in 0pt .5in;text-indent:-.25in;"><span style="font-size:medium;"><br /></span></p>
<p class="MsoListParagraph" style="margin:0in 0in 0pt .5in;text-indent:-.25in;"><span style="font-size:medium;"><span>这些规则听起来可能有些神秘，但是他们来源于两条简单的规则：</span></span></p>
<p class="MsoListParagraph" style="margin:0in 0in 0pt .5in;text-indent:-.25in;"><span style="font-size:medium;"><br /></span></p>
<p class="MsoListParagraph" style="margin:0in 0in 0pt .5in;text-indent:-.25in;"><span style="font-size:medium;"><span>· </span></span><span style="font-size:medium;"><span>遵守 const 正确性，</span></span><span style="font-size:medium;"><span>所以你不能把</span></span><span style="font-size:medium;">非常量</span><span style="font-size:medium;"><span>引用绑定到常量上。</span></span></p>
<p class="MsoListParagraph" style="margin:0in 0in 0pt .5in;text-indent:-.25in;"><span style="font-size:medium;"><br /></span></p>
<p class="MsoListParagraph" style="margin:0in 0in 0pt .5in;text-indent:-.25in;"><span style="font-size:medium;"><span>· </span></span><span style="font-size:medium;"><span>避免意外修改临时对象，所以你不能把</span></span><span style="font-size:medium;">非常量</span><span style="font-size:medium;"><span> lvalue 引用绑定到</span></span><span style="font-size:medium;">非常量</span><span style="font-size:medium;"><span> rvalue 上来。<br /></span></span></p>
<p><span style="font-size:medium;"><br /></span></p>
<p><span style="font-size:medium;">如果你更喜欢阅读编译器错误信息，而不是阅读文字描述，下面是一个示例：</span></p>
<p><span style="font-size:medium;"><br /></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">C:\Temp&gt;type initialization.cpp</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">#include &lt;string&gt;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">using namespace std;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">string modifiable_rvalue() {</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    return "cute";</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">}</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">const string const_rvalue() {</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    return "fluffy";</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">}</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">int main() {</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    string modifiable_lvalue("kittens");</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    const string const_lvalue("hungry hungry zombies");</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    string&amp; a = modifiable_lvalue;          // Line 16</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    string&amp; b = const_lvalue;               // Line 17 - ERROR</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    string&amp; c = modifiable_rvalue();        // Line 18 - ERROR</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    string&amp; d = const_rvalue();             // Line 19 - ERROR</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    const string&amp; e = modifiable_lvalue;    // Line 21</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    const string&amp; f = const_lvalue;         // Line 22</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    const string&amp; g = modifiable_rvalue();  // Line 23</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    const string&amp; h = const_rvalue();       // Line 24</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    string&amp;&amp; i = modifiable_lvalue;         // Line 26</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    string&amp;&amp; j = const_lvalue;              // Line 27 - ERROR</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    string&amp;&amp; k = modifiable_rvalue();       // Line 28</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    string&amp;&amp; l = const_rvalue();            // Line 29 - ERROR</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    const string&amp;&amp; m = modifiable_lvalue;   // Line 31</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    const string&amp;&amp; n = const_lvalue;        // Line 32</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    const string&amp;&amp; o = modifiable_rvalue(); // Line 33</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    const string&amp;&amp; p = const_rvalue();      // Line 34</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">}</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">C:\Temp&gt;cl /EHsc /nologo /W4 /WX initialization.cpp</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">initialization.cpp</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">initialization.cpp(17) : error C2440: 'initializing' : cannot convert from 'const std::string' to 'std::string &amp;'</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">        Conversion loses qualifiers</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">initialization.cpp(18) : warning C4239: nonstandard extension used : 'initializing' : conversion from 'std::string' to 'std::string &amp;'</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">        A non-const reference may only be bound to an lvalue</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">initialization.cpp(19) : error C2440: 'initializing' : cannot convert from 'const std::string' to 'std::string &amp;'</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">        Conversion loses qualifiers</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">initialization.cpp(27) : error C2440: 'initializing' : cannot convert from 'const std::string' to 'std::string &amp;&amp;'</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">        Conversion loses qualifiers</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">initialization.cpp(29) : error C2440: 'initializing' : cannot convert from 'const std::string' to 'std::string &amp;&amp;'</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">        Conversion loses qualifiers</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><br /></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">非常量</span><span style="font-size:medium;"> rvalue 引用绑定到</span><span style="font-size:medium;">非常量</span><span style="font-size:medium;"> rvalue 是没问题的；要领就是它们可以被用来修改临时对象。</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><br /></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">虽然 lvalue 引用和 rvalue 引用在初始化时有着相似的行为（只有第 18 和 28 行不同），但在重载决议的时候它们的区别就很显著了。</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><br /></span></p>
<p style="text-align:center;"><span style="font-size:medium;">&lt;  </span><span style="font-size:medium;"><a href="http://www.yeeyan.com/articles/view/kesalin/43500">本页</a>  <a href="http://www.yeeyan.com/articles/view/kesalin/43772" target="_blank">第二页</a>  <a href="http://www.yeeyan.com/articles/view/kesalin/43774" target="_blank">第三页</a></span>  <span style="font-size:medium;"><a target="_self">第四页</a>  </span><span style="font-size:medium;"><a target="_self">第五页</a> &gt;<br /></span></p><p><a href="http://www.yeeyan.com/articles/view/kesalin/43500#newComment">添加评论</a></p>
<p><embed id="movie_rss" height="60" width="468" quality="high" bgcolor="#ffffff" name="mymovie" style="" src="http://www.yeeyan.com/files/newindexads/vancl_090622_468_rss.swf" type="application/x-shockwave-flash"/></p>
]]>
        </content>
    <feedburner:origLink>http://www.yeeyan.com/articles/view/kesalin/43500</feedburner:origLink></entry>
    <entry>
        <title>VC10中的C&amp;#43;&amp;#43;0x特性 Part 1 &amp;#40;3&amp;#41; : Lambdas，auto，以及 static_assert</title>
        <link href="http://feedproxy.google.com/~r/yeeyan_lang/~3/H-xA5rTOTVg/43573" />
        <created>2009-05-29T02:32:15+00:00</created>
        <issued>2009-05-29T02:32:15+00:00</issued>
        <modified>2009-05-29T02:32:15+00:00</modified>
        <published>2009-05-29T02:32:15+00:00</published>
        <id>tag:feed.yeeyan.com:translation/43573</id>
        <category term="科学技术" scheme="feed.yeeyan.com" label="科学技术" />
        <author>
            <name>飘飘白云</name>
            <uri>http://www.yeeyan.com/space/show/kesalin</uri>
        </author>
        <content type="html">
            <![CDATA[<p>原文作者：Visual C&#43;&#43; Team Blog<br />原文链接：<a href="http://blogs.msdn.com/vcblog/archive/2008/10/28/lambdas-auto-and-static-assert-c-0x-features-in-vc10-part-1.aspx">Lambdas, auto, and static_assert: C&#43;&#43;0x Features in VC10 Part1&#40;3&#41;</a><br/>译者：<a href="http://www.yeeyan.com/space/show/kesalin">飘飘白云</a></p><p class="MsoNormal" style="margin:0mm 0mm 0pt;text-align:center;"><span style="font-size:medium;"><strong>VC10中的C++0x特性 Part 1 (3) : Lambdas，auto，以及 static_assert</strong></span></p>
<p class="MsoNormal" style="margin:0mm 0mm 0pt;text-align:center;"> </p>
<p class="MsoNormal" style="margin:0mm 0mm 0pt;text-align:center;"><span style="font-size:medium;"><strong>来源：<a title="vcvlog" href="http://blogs.msdn.com/vcblog/archive/2008/10/28/lambdas-auto-and-static-assert-c-0x-features-in-vc10-part-1.aspx" target="_blank">vcblog</a> 翻译：<a href="http://www.cppblog.com/kesalin">飘飘白云</a> kesalin@gmail.com</strong></span></p>
<p class="MsoNormal" style="margin:0mm 0mm 0pt;"> </p>
<p class="MsoNormal" style="margin:0mm 0mm 0pt;text-align:center;"><span style="font-size:medium;">共三页： <a href="http://www.yeeyan.com/articles/view/kesalin/43288">第一页</a> <a href="http://www.yeeyan.com/articles/view/kesalin/43571">第二页</a> <a href="http://www.yeeyan.com/articles/view/kesalin/43573">本页<br /></a></span></p>
<p class="MsoNormal" style="margin:0mm 0mm 0pt;text-align:center;"> </p>
<p class="MsoNormal"><span style="font-size:medium;">注意可选的 lambda 参数声明语法上包括：</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><span style="font-family:Consolas;">(</span> <em>lambda-parameter-declaration-list<sub>opt</sub></em> <span style="font-family:Consolas;">)</span> <span style="font-family:Consolas;">mutable</span><em><sub>opt</sub> exception-specification<sub>opt</sub> lambda-return-type-clause<sub>opt</sub></em></span></p>
<p class="MsoNormal"> </p>
<p class="MsoNormal"><span style="font-size:medium;">因此，如果你想使用 </span><span style="font-size:medium;"><span style="font-family:Consolas;">mutable</span> </span><span style="font-size:medium;">或<strong> </strong></span><span style="font-size:medium;"> <span style="font-family:Consolas;">-&gt; ReturnType</span></span><span style="font-size:medium;">，你需要在 lambda 导引符和它们之间插入空括号。</span></p>
<p class="MsoNormal"><span style="font-size:medium;">最后，因为 lambda 产生普通的函数对象，你可以在 tr1::function 中存储它们。</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-family:Consolas;"><span style="font-size:medium;">C:\Temp&gt;type tr1kitty.cpp</span></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-family:Consolas;"><span style="font-size:medium;">#include &lt;algorithm&gt;</span></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-family:Consolas;"><span style="font-size:medium;">#include &lt;functional&gt;</span></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-family:Consolas;"><span style="font-size:medium;">#include &lt;iostream&gt;</span></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-family:Consolas;"><span style="font-size:medium;">#include &lt;ostream&gt;</span></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-family:Consolas;"><span style="font-size:medium;">#include &lt;vector&gt;</span></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-family:Consolas;"><span style="font-size:medium;">using namespace std;</span></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-family:Consolas;"><span style="font-size:medium;">using namespace std::tr1;</span></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-family:Consolas;"><span style="font-size:medium;"> </span></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-family:Consolas;"><span style="font-size:medium;">void meow(const vector&lt;int&gt;&amp; v, <strong>const function&lt;void (int)&gt;&amp; f</strong>) {</span></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-family:Consolas;"><span style="font-size:medium;">    for_each(v.begin(), v.end(), f);</span></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-family:Consolas;"><span style="font-size:medium;">    cout &lt;&lt; endl;</span></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-family:Consolas;"><span style="font-size:medium;">}</span></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-family:Consolas;"><span style="font-size:medium;"> </span></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-family:Consolas;"><span style="font-size:medium;">int main() {</span></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-family:Consolas;"><span style="font-size:medium;">    vector&lt;int&gt; v;</span></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-family:Consolas;"><span style="font-size:medium;"> </span></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-family:Consolas;"><span style="font-size:medium;">    for (int i = 0; i &lt; 10; ++i) {</span></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-family:Consolas;"><span style="font-size:medium;">        v.push_back(i);</span></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-family:Consolas;"><span style="font-size:medium;">    }</span></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-family:Consolas;"><span style="font-size:medium;"> </span></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-family:Consolas;"><span style="font-size:medium;">    meow(v, <strong>[](int n) { cout &lt;&lt; n &lt;&lt; " "; }</strong>);</span></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-family:Consolas;"><span style="font-size:medium;">    meow(v, <strong>[](int n) { cout &lt;&lt; n * n &lt;&lt; " "; }</strong>);</span></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-family:Consolas;"><span style="font-size:medium;"> </span></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-family:Consolas;"><span style="font-size:medium;">    <strong>function&lt;void (int)&gt; g = [](int n) { cout &lt;&lt; n * n * n &lt;&lt; " "; };</strong></span></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-family:Consolas;"><span style="font-size:medium;"> </span></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-family:Consolas;"><span style="font-size:medium;">    meow(v, g);</span></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-family:Consolas;"><span style="font-size:medium;">}</span></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-family:Consolas;"><span style="font-size:medium;"> </span></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-family:Consolas;"><span style="font-size:medium;">C:\Temp&gt;cl /EHsc /nologo /W4 tr1kitty.cpp &gt; NUL &amp;&amp; tr1kitty</span></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-family:Consolas;"><span style="font-size:medium;">0 1 2 3 4 5 6 7 8 9</span></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-family:Consolas;"><span style="font-size:medium;">0 1 4 9 16 25 36 49 64 81</span></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-family:Consolas;"><span style="font-size:medium;">0 1 8 27 64 125 216 343 512 729</span></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"> </p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"> </p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:large;"><strong>auto</strong></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><br /></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">关键词 auto 是从 C++ 98 得来的，它在 C++ 98 中实际上并没起什么作用，但在 C++ 0x 中被重用于自动类型推导（</span><span style="font-size:medium;">automatic type deduction</span><span style="font-size:medium;">）。 在一个声明中使用 auto ，意味着“让它和初始化它的事物具有相同的类型”。你看：</span></p>
<p> </p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-family:Consolas;"><span style="font-size:medium;">C:\Temp&gt;type autocat.cpp</span></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-family:Consolas;"><span style="font-size:medium;">#include &lt;iostream&gt;</span></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-family:Consolas;"><span style="font-size:medium;">#include &lt;map&gt;</span></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-family:Consolas;"><span style="font-size:medium;">#include &lt;ostream&gt;</span></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-family:Consolas;"><span style="font-size:medium;">#include &lt;regex&gt;</span></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-family:Consolas;"><span style="font-size:medium;">#include &lt;string&gt;</span></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-family:Consolas;"><span style="font-size:medium;">using namespace std;</span></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-family:Consolas;"><span style="font-size:medium;">using namespace std::tr1;</span></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-family:Consolas;"><span style="font-size:medium;"> </span></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-family:Consolas;"><span style="font-size:medium;">int main() {</span></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-family:Consolas;"><span style="font-size:medium;">    map&lt;string, string&gt; m;</span></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-family:Consolas;"><span style="font-size:medium;"> </span></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-family:Consolas;"><span style="font-size:medium;">    <span style="font-size:12pt;font-family:Consolas;">const regex r("(<a>\\w</a>+) (<a>\\w+)</a>");</span></span></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-family:Consolas;"><span style="font-size:medium;"> </span></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-family:Consolas;"><span style="font-size:medium;">    for (string s; getline(cin, s); ) {</span></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-family:Consolas;"><span style="font-size:medium;">        smatch results;</span></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-family:Consolas;"><span style="font-size:medium;"> </span></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-family:Consolas;"><span style="font-size:medium;">        if (regex_match(s, results, r)) {</span></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-family:Consolas;"><span style="font-size:medium;">            m[results[1]] = results[2];</span></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-family:Consolas;"><span style="font-size:medium;">        }</span></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-family:Consolas;"><span style="font-size:medium;">    }</span></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-family:Consolas;"><span style="font-size:medium;"> </span></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-family:Consolas;"><span style="font-size:medium;">    for (<strong>auto</strong> i = m.begin(); i != m.end(); ++i) {</span></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-family:Consolas;"><span style="font-size:medium;">        cout &lt;&lt; i-&gt;second &lt;&lt; " are " &lt;&lt; i-&gt;first &lt;&lt; endl;</span></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-family:Consolas;"><span style="font-size:medium;">    }</span></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-family:Consolas;"><span style="font-size:medium;">}</span></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-family:Consolas;"><span style="font-size:medium;"> </span></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-family:Consolas;"><span style="font-size:medium;">C:\Temp&gt;cl /EHsc /nologo /W4 autocat.cpp &gt; NUL &amp;&amp; autocat</span></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-family:Consolas;"><span style="font-size:medium;">cute kittens</span></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-family:Consolas;"><span style="font-size:medium;">ugly puppies</span></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-family:Consolas;"><span style="font-size:medium;">evil goblins</span></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-family:Consolas;"><span style="font-size:medium;">^Z</span></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-family:Consolas;"><span style="font-size:medium;">kittens are cute</span></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-family:Consolas;"><span style="font-size:medium;">goblins are evil</span></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-family:Consolas;"><span style="font-size:medium;">puppies are ugly</span></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"> </p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><strong>map&lt;string, string&gt;::iterator</strong>，你近10年的恐怖统治终于到头了。</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><br /></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">（注意：m.begin()返回 <strong>iterator</strong>，而不是 <strong>cosnt_iterator</strong>，因为 <strong>map </strong>不是 <strong>const </strong>属性的。C++ 0x <strong>cbegin()</strong> 允许你从一个 <strong>non-cosnt</strong> 容器中获得一个 <strong>const_iterator</strong>。）</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><br /></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:large;"><strong>lambdas and auto</strong></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"> </p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">先前我提到</span><span style="font-size:medium;">过在 </span><span style="font-size:medium;">tr1::functions 中存储 lambda 函数。但是如非必要请别这么做，因为 </span><span style="font-size:medium;"><strong>tr1::function</strong> 会增加一些开销。如果你想重用 lambda 函数，或只想给它命名的话，你可以使用 <strong>auto</strong>。这儿有一个简洁的例子：</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">C:\Temp&gt;type autolambdakitty.cpp</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">#include &lt;algorithm&gt;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">#include &lt;iostream&gt;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">#include &lt;ostream&gt;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">#include &lt;vector&gt;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">using namespace std;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">template &lt;typename T, typename Predicate&gt; void keep_if(vector&lt;T&gt;&amp; v, Predicate pred) {</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><strong>    auto notpred = [&amp;](const T&amp; t) {</strong></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><strong>        return !pred(t);</strong></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><strong>    };</strong></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">    v.erase(remove_if(v.begin(), v.end(), <strong>notpred</strong>), v.end());</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">}</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">template &lt;typename Container&gt; void print(const Container&amp; c) {</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">    for_each(c.begin(), c.end(), [](const typename Container::value_type&amp; e) { cout &lt;&lt; e &lt;&lt; " "; });</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">    cout &lt;&lt; endl;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">}</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">int main() {</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">    vector&lt;int&gt; a;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">    for (int i = 0; i &lt; 100; ++i) {</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">        a.push_back(i);</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">    }</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">    vector&lt;int&gt; b;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">    for (int i = 100; i &lt; 200; ++i) {</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">        b.push_back(i);</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">    }</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><strong>    auto prime = [](const int n) -&gt; bool {</strong></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><strong>        if (n &lt; 2) {</strong></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><strong>            return false;</strong></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><strong>        }</strong></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><strong> </strong></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><strong>        for (int i = 2; i &lt;= n / i; ++i) {</strong></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><strong>            if (n % i == 0) {</strong></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><strong>                return false;</strong></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><strong>            }</strong></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><strong>        }</strong></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><strong> </strong></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><strong>        return true;</strong></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><strong>    };</strong></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">    keep_if(a, <strong>prime</strong>);</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">    keep_if(b, <strong>prime</strong>);</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">    print(a);</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">    print(b);</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">}</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">C:\Temp&gt;cl /EHsc /nologo /W4 autolambdakitty.cpp</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">autolambdakitty.cpp</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">C:\Temp&gt;autolambdakitty</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Consolas;">101 103 107 109 113 127 131 137 139 149 151 157 163 167 173 179 181 191 193 197 199</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><br /></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><strong>notpred</strong> 是一个否定 lambda 函数，注意我们不能使用 C++ 98 </span><span style="font-size:medium;"><strong>&lt;functional&gt;</strong>中的 </span><span style="font-size:medium;"><strong>not1()</strong> 函数，因为那要求你的谓词函数</span><span style="font-size:medium;">继承</span><span style="font-size:medium;">自 </span><span style="font-size:medium;"><strong>unary_function</strong>，而 lambda 函数并不满足这个条件。</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><br /></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:large;"><strong>static_assert</strong></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><br /></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><strong>static_assert </strong>让你能够在</span><span style="font-size:medium;">触发</span><span style="font-size:medium;">编译器错误时使用定制的错误信息:</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"> </p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">C:\Temp&gt;type staticfluffykitten.cpp</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">template &lt;int N&gt; struct Kitten {</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    <strong>static_assert(N &lt; 2, "Kitten&lt;N&gt; requires N &lt; 2.");</strong></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">};</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">int main() {</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    Kitten&lt;1&gt; peppermint;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    Kitten&lt;3&gt; jazz;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">}</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">C:\Temp&gt;cl /EHsc /nologo /W4 staticfluffykitten.cpp</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">staticfluffykitten.cpp</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">staticfluffykitten.cpp(2) : <strong>error C2338: Kitten&lt;N&gt; requires N &lt; 2.</strong></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">        staticfluffykitten.cpp(8) : see reference to class template instantiation 'Kitten&lt;N&gt;' being compiled</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">        with</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">        [</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">            N=3</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">        ]</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><br /></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">如果你有任何疑问，我很乐意在评论中回答它们。<br /></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><br /></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Verdana;">Stephan T. Lavavej</span></p>
<p><span style="font-size:medium;font-family:Verdana;">Visual C++ Libraries Developer</span></p>
<p><span style="font-size:medium;">Published Tuesday, October 28, 2008 9:31 AM 			by 			<a href="http://blogs.msdn.com/user/Profile.aspx?UserID=33825">vcblog</a></span></p>
<p> </p><p><a href="http://www.yeeyan.com/articles/view/kesalin/43573#newComment">添加评论</a></p>
<p><embed id="movie_rss" height="60" width="468" quality="high" bgcolor="#ffffff" name="mymovie" style="" src="http://www.yeeyan.com/files/newindexads/vancl_090622_468_rss.swf" type="application/x-shockwave-flash"/></p>
]]>
        </content>
    <feedburner:origLink>http://www.yeeyan.com/articles/view/kesalin/43573</feedburner:origLink></entry>
    <entry>
        <title>VC10中的C&amp;#43;&amp;#43;0x特性 Part 1 &amp;#40;2&amp;#41; : Lambdas，auto，以及 static_assert</title>
        <link href="http://feedproxy.google.com/~r/yeeyan_lang/~3/E6Io5b-sLrA/43571" />
        <created>2009-05-29T02:10:52+00:00</created>
        <issued>2009-05-29T02:10:52+00:00</issued>
        <modified>2009-05-29T02:10:52+00:00</modified>
        <published>2009-05-29T02:10:52+00:00</published>
        <id>tag:feed.yeeyan.com:translation/43571</id>
        <category term="科学技术" scheme="feed.yeeyan.com" label="科学技术" />
        <author>
            <name>飘飘白云</name>
            <uri>http://www.yeeyan.com/space/show/kesalin</uri>
        </author>
        <content type="html">
            <![CDATA[<p>原文作者：VCBlog<br />原文链接：<a href="http://blogs.msdn.com/vcblog/archive/2008/10/28/lambdas-auto-and-static-assert-c-0x-features-in-vc10-part-1.aspx">Lambdas, auto, and static_assert: C&#43;&#43;0x Features in VC10 Part1&#40;2&#41;</a><br/>译者：<a href="http://www.yeeyan.com/space/show/kesalin">飘飘白云</a></p><p class="MsoNormal" style="margin:0mm 0mm 0pt;text-align:center;"><span style="font-size:medium;"><strong>VC10中的C++0x特性 Part 1 (2) : Lambdas，auto，以及 static_assert</strong></span></p>
<p class="MsoNormal" style="margin:0mm 0mm 0pt;text-align:center;"> </p>
<p class="MsoNormal" style="margin:0mm 0mm 0pt;text-align:center;"><span style="font-size:medium;"><strong>来源：<a title="vcvlog" href="http://blogs.msdn.com/vcblog/archive/2008/10/28/lambdas-auto-and-static-assert-c-0x-features-in-vc10-part-1.aspx" target="_blank">vcblog</a> 翻译：<a href="http://www.cppblog.com/kesalin">飘飘白云</a> kesalin@gmail.com</strong></span></p>
<p class="MsoNormal" style="margin:0mm 0mm 0pt;"> </p>
<p class="MsoNormal" style="margin:0mm 0mm 0pt;text-align:center;"><span style="font-size:medium;">共三页： <a href="http://www.yeeyan.com/articles/view/kesalin/43288">第一页</a> <a href="http://www.yeeyan.com/articles/view/kesalin/43571">本页</a> <a href="http://www.yeeyan.com/articles/view/kesalin/43573">第三页</a></span></p>
<p class="MsoNormal" style="margin:0mm 0mm 0pt;text-align:center;"> </p>
<p><span style="font-size:medium;">情形（a）要修改通过传递（capture）获得拷贝该怎样呢？默认情况下，一个 lambda 函数调用操作符是 const 属性的，但是可以通过使用 <strong>mutable </strong>把它变成 <strong>non-const</strong>。</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">C:\Temp&gt;type capturekittybymutablevalue.cpp</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">#include &lt;algorithm&gt;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">#include &lt;iostream&gt;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">#include &lt;ostream&gt;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">#include &lt;vector&gt;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">using namespace std;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">int main() {</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    vector&lt;int&gt; v;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    for (int i = 0; i &lt; 10; ++i) {</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">        v.push_back(i);</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    }</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    int x = 1;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    int y = 1;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    for_each(v.begin(), v.end(), <strong>[=](int&amp; r) mutable {</strong></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><strong><span style="font-size:medium;">        const int old = r;</span></strong></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><strong><span style="font-size:medium;"> </span></strong></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><strong><span style="font-size:medium;">        r *= x * y;</span></strong></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><strong><span style="font-size:medium;"> </span></strong></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><strong><span style="font-size:medium;">        x = y;</span></strong></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><strong><span style="font-size:medium;">        y = old;</span></strong></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><strong>    }</strong>);</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    for_each(v.begin(), v.end(), [](int n) { cout &lt;&lt; n &lt;&lt; " "; });</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    cout &lt;&lt; endl;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    cout &lt;&lt; x &lt;&lt; ", " &lt;&lt; y &lt;&lt; endl;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">}</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">C:\Temp&gt;cl /EHsc /nologo /W4 capturekittybymutablevalue.cpp &gt; NUL &amp;&amp; capturekittybymutablevalue</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">0 0 0 6 24 60 120 210 336 504</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">1, 1</span></p>
<p class="MsoNormal"><span style="font-size:medium;">这里是依次将 <strong>v</strong> 中前两个元素相乘。（我得承认真的很难想出一个不用 <span>partial_sum() 或 <span>adjacent_difference() </span>表示的例子，<span>partial_sum() 是与前面所有的元素相乘，<span>adjacent_difference()是与前一个元素相乘）。注意到情形（d），对通过传递获得的拷贝的更新操作并没有影响局部变量（再一次，原始值语义）。</span></span></span></span></p>
<p> </p>
<p><span style="font-size:medium;">如果你想处理情形（b），（c）和（d）：避免拷贝，在 lambda 中观察局部变量的更新，以及在 lambda 中修改局部变量又该怎么做呢？在这种情况下，你会想通过引用传递（capture by reference）。其语法是这种形式的 lambda 导引符<strong> <span>[&amp;x, &amp;y]</span> </strong>（你可以把它想象成  <strong><span>X&amp; x, Y&amp; y</span></strong> ; 那是“引用”而不是“取址”）。</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">C:\Temp&gt;type capturekittybyreference.cpp</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">#include &lt;algorithm&gt;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">#include &lt;iostream&gt;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">#include &lt;ostream&gt;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">#include &lt;vector&gt;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">using namespace std;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">int main() {</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    vector&lt;int&gt; v;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    for (int i = 0; i &lt; 10; ++i) {</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">        v.push_back(i);</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    }</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    int x = 1;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    int y = 1;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    for_each(v.begin(), v.end(), <strong>[&amp;x, &amp;y](int&amp; r) {</strong></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><strong><span style="font-size:medium;">        const int old = r;</span></strong></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><strong><span style="font-size:medium;"> </span></strong></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><strong><span style="font-size:medium;">        r *= x * y;</span></strong></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><strong><span style="font-size:medium;"> </span></strong></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><strong><span style="font-size:medium;">        x = y;</span></strong></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><strong><span style="font-size:medium;">        y = old;</span></strong></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><strong>    }</strong>);</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    for_each(v.begin(), v.end(), [](int n) { cout &lt;&lt; n &lt;&lt; " "; });</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    cout &lt;&lt; endl;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    cout &lt;&lt; x &lt;&lt; ", " &lt;&lt; y &lt;&lt; endl;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">}</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">C:\Temp&gt;cl /EHsc /nologo /W4 capturekittybyreference.cpp &gt; NUL &amp;&amp; capturekittybyreference</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">0 0 0 6 24 60 120 210 336 504</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">8, 9</span></p>
<p class="MsoNormal"><span style="font-size:medium;">注意与 capturekittybymutablevalue.cpp 的区别：（1），lambda 导引符是 <strong><span>[&amp;x, &amp;y]</span></strong> ，（2）没有 <strong>mutable</strong>，（3），局部变量 x 和 y 最后的值是 8 和 9，反应了在 lambda 中对他们的修改。</span></p>
<p class="MsoNormal"><span style="font-size:medium;">上面的代码在内部被翻译成：</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">C:\Temp&gt;type capturekittybyreference98.cpp</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">#include &lt;algorithm&gt;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">#include &lt;iostream&gt;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">#include &lt;iterator&gt;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">#include &lt;ostream&gt;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">#include &lt;vector&gt;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">using namespace std;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><strong><span style="font-size:medium;">#pragma warning(push)</span></strong></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><strong><span style="font-size:medium;">#pragma warning(disable: 4512) // assignment operator could not be generated</span></strong></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><strong><span style="font-size:medium;"> </span></strong></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><strong><span style="font-size:medium;">class LambdaFunctor {</span></strong></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><strong><span style="font-size:medium;">public:</span></strong></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><strong><span style="font-size:medium;">    LambdaFunctor(int&amp; a, int&amp; b) : m_a(a), m_b(b) { }</span></strong></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><strong><span style="font-size:medium;"> </span></strong></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><strong><span style="font-size:medium;">    void operator()(int&amp; r) const {</span></strong></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><strong><span style="font-size:medium;">        const int old = r;</span></strong></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><strong><span style="font-size:medium;"> </span></strong></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><strong><span style="font-size:medium;">        r *= m_a * m_b;</span></strong></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><strong><span style="font-size:medium;"> </span></strong></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><strong><span style="font-size:medium;">        m_a = m_b;</span></strong></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><strong><span style="font-size:medium;">        m_b = old;</span></strong></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><strong><span style="font-size:medium;">    }</span></strong></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><strong><span style="font-size:medium;"> </span></strong></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><strong><span style="font-size:medium;">private:</span></strong></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><strong><span style="font-size:medium;">    int&amp; m_a;</span></strong></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><strong><span style="font-size:medium;">    int&amp; m_b;</span></strong></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><strong><span style="font-size:medium;">};</span></strong></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><strong><span style="font-size:medium;"> </span></strong></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><strong><span style="font-size:medium;">#pragma warning(pop)</span></strong></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">int main() {</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    vector&lt;int&gt; v;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    for (int i = 0; i &lt; 10; ++i) {</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">        v.push_back(i);</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    }</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    int x = 1;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    int y = 1;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    for_each(v.begin(), v.end(), <strong>LambdaFunctor(x, y)</strong>);</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    copy(v.begin(), v.end(), ostream_iterator&lt;int&gt;(cout, " "));</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    cout &lt;&lt; endl;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    cout &lt;&lt; x &lt;&lt; ", " &lt;&lt; y &lt;&lt; endl;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">}</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">C:\Temp&gt;cl /EHsc /nologo /W4 capturekittybyreference98.cpp &gt; NUL &amp;&amp; capturekittybyreference98</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">0 0 0 6 24 60 120 210 336 504</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">8, 9</span></p>
<p class="MsoNormal"><span style="font-size:medium;">当你通过引用传递（capture）局部变量时，函数对象存储局部变量的引用。这样避免了拷贝，能够让函数对象观测对局部变量的更新，以及能够让函数对象通过引用修改局部变量。（注意函数调用操作符是 <strong>const</strong> 属性的，因为我们没有把它声明成 <strong>mutable</strong>，但这只阻止我们修改函数对象的数据成员。在这里数据成员是引用，我们无法修改它，但是我们可以修改它所指向的东西。函数调用操作符的常量性是,且一直都是，表面的）</span></p>
<p class="MsoNormal"> </p>
<p class="MsoNormal"><span style="font-size:medium;">当然，如果函数对象比用于引用传递的局部变量的生命期更长的话，程序会毁灭性地崩溃。（译注：就是说引用所指向的东西已经销毁了，但你可能还在</span><span style="font-size:medium;">使用这个引用</span><span style="font-size:medium;">）</span></p>
<p class="MsoNormal"> </p>
<p class="MsoNormal"><span style="font-size:medium;">同样，你可以使用默认的按引用传递语法；这种形式 lambder 导引符<strong> [&amp;] </strong>表明“按引用传递”。</span></p>
<p class="MsoNormal"> </p>
<p class="MsoNormal"><span style="font-size:medium;">如果你想混合使用按值传递和按引用传递该怎么做呢？你可以像这样声明<strong> </strong><span><strong>[a, b, c, &amp;d, e, &amp;f, g]</strong>，但你也可以指定默认按值传递，再为特定的（需要按引用传递的）局部变量而重载它。下面是一个修改capturekittybymutablevalue.cpp 而来的例子：</span></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">C:\Temp&gt;type overridekitty.cpp</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">#include &lt;algorithm&gt;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">#include &lt;iostream&gt;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">#include &lt;ostream&gt;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">#include &lt;vector&gt;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">using namespace std;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">int main() {</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    vector&lt;int&gt; v;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    for (int i = 0; i &lt; 10; ++i) {</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">        v.push_back(i);</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    }</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    int sum = 0;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    int product = 1;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    int x = 1;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    int y = 1;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    for_each(v.begin(), v.end(), <strong>[=, &amp;sum, &amp;product](int&amp; r) mutable {</strong></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><strong><span style="font-size:medium;">        sum += r;</span></strong></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><strong><span style="font-size:medium;"> </span></strong></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><strong><span style="font-size:medium;">        if (r != 0) {</span></strong></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><strong><span style="font-size:medium;">            product *= r;</span></strong></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><strong><span style="font-size:medium;">        }</span></strong></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><strong><span style="font-size:medium;"> </span></strong></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><strong><span style="font-size:medium;">        const int old = r;</span></strong></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><strong><span style="font-size:medium;"> </span></strong></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><strong><span style="font-size:medium;">        r *= x * y;</span></strong></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><strong><span style="font-size:medium;"> </span></strong></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><strong><span style="font-size:medium;">        x = y;</span></strong></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><strong><span style="font-size:medium;">        y = old;</span></strong></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><strong>    }</strong>);</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    for_each(v.begin(), v.end(), [](int n) { cout &lt;&lt; n &lt;&lt; " "; });</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    cout &lt;&lt; endl;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    cout &lt;&lt; "sum: " &lt;&lt; sum &lt;&lt; ", product: " &lt;&lt; product &lt;&lt; endl;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    cout &lt;&lt; "x: " &lt;&lt; x &lt;&lt; ", y: " &lt;&lt; y &lt;&lt; endl;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">}</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">C:\Temp&gt;cl /EHsc /nologo /W4 overridekitty.cpp &amp;&amp; overridekitty</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">overridekitty.cpp</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">0 0 0 6 24 60 120 210 336 504</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">sum: 45, product: 362880</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">x: 1, y: 1</span></p>
<p class="MsoNormal"> </p>
<p class="MsoNormal"><span style="font-size:medium;">在这里，我们想通过按值传递 <strong>x</strong> 和 <strong>y</strong> （因为我们只想在 lambda 内部修改它们，而影响外部），同时我们想按传引用捕获 <strong>sum </strong>和 <strong>product</strong>（因为我们确实想让对它们的修改在外部也生效）。像这样的 lambda 导入符组合 <strong><span>[&amp;, x, y]</span></strong> 可以起到同样的效果（按应用传递所有参数，除了 x 和 y 是按值传递之外）</span></p>
<p class="MsoNormal"> </p>
<p class="MsoNormal"><span style="font-size:medium;">嗯，如果你想这么做又该如何？<br /></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">C:\Temp&gt;type memberkitty.cpp</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">#include &lt;algorithm&gt;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">#include &lt;iostream&gt;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">#include &lt;ostream&gt;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">#include &lt;vector&gt;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">using namespace std;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">class Kitty {</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">public:</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    explicit Kitty(int toys) : m_toys(toys) { }</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    void meow(const vector&lt;int&gt;&amp; v) const {</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">        for_each(v.begin(), v.end(), <strong>[m_toys](int n) {</strong></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><strong><span style="font-size:medium;">            cout &lt;&lt; "If you gave me " &lt;&lt; n &lt;&lt; " toys, I would have " &lt;&lt; n + m_toys &lt;&lt; " toys total." &lt;&lt; endl;</span></strong></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><strong>        }</strong>);</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    }</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">private:</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    int m_toys;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">};</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">int main() {</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    vector&lt;int&gt; v;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    for (int i = 0; i &lt; 3; ++i) {</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">        v.push_back(i);</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    }</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    Kitty k(5);</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    k.meow(v);</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">}</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">C:\Temp&gt;cl /EHsc /nologo /W4 memberkitty.cpp</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">memberkitty.cpp</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">memberkitty.cpp(12) : <strong>error C3480: 'Kitty::m_toys': a lambda capture variable must be from an enclosing function scope</strong></span></p>
<p class="MsoNormal"> </p>
<p class="MsoNormal"><span style="font-size:medium;">lambda 表达式语法允许你传递局部变量，但是数据成员不是局部变量。通过特别的方法，你也可以传递数据成员：</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">C:\Temp&gt;type workingmemberkitty.cpp</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">#include &lt;algorithm&gt;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">#include &lt;iostream&gt;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">#include &lt;ostream&gt;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">#include &lt;vector&gt;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">using namespace std;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">class Kitty {</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">public:</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    explicit Kitty(int toys) : m_toys(toys) { }</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    void meow(const vector&lt;int&gt;&amp; v) const {</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">        for_each(v.begin(), v.end(), <strong>[this](int n) {</strong></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><strong><span style="font-size:medium;">            cout &lt;&lt; "If you gave me " &lt;&lt; n &lt;&lt; " toys, I would have " &lt;&lt; n + m_toys &lt;&lt; " toys total." &lt;&lt; endl;</span></strong></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><strong>        }</strong>);</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    }</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">private:</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    int m_toys;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">};</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">int main() {</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    vector&lt;int&gt; v;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    for (int i = 0; i &lt; 3; ++i) {</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">        v.push_back(i);</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    }</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    Kitty k(5);</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    k.meow(v);</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">}</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">C:\Temp&gt;cl /EHsc /nologo /W4 workingmemberkitty.cpp &gt; NUL &amp;&amp; workingmemberkitty</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">If you gave me 0 toys, I would have 5 toys total.</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">If you gave me 1 toys, I would have 6 toys total.</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">If you gave me 2 toys, I would have 7 toys total.</span></p>
<p class="MsoNormal"> </p>
<p class="MsoNormal"><span style="font-size:medium;">当你传递 <strong>this</strong>，你可以使用 <strong>m_toys</strong>，它隐含意味着 <strong><span>this-&gt;m_toys</span></strong>，就如平常一样（译注：作为类自身成员变量）。你也可以显式使用 <span><strong>this-&gt;m_toys</strong>。（在一个 lambda 表达式内，只有当你传递了 <strong>this</strong>，你才能使用它；你永不可能取得 lambda 对象它自身的 <strong>this </strong>指针）。</span></span></p>
<p class="MsoNormal"> </p>
<p class="MsoNormal"><span style="font-size:medium;">你也可以隐式地传递 <strong>this </strong>：</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">C:\Temp&gt;type implicitmemberkitty.cpp</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">#include &lt;algorithm&gt;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">#include &lt;iostream&gt;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">#include &lt;ostream&gt;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">#include &lt;vector&gt;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">using namespace std;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">class Kitty {</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">public:</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    explicit Kitty(int toys) : m_toys(toys) { }</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    void meow(const vector&lt;int&gt;&amp; v) const {</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">        for_each(v.begin(), v.end(), <strong>[=](int n) {</strong></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><strong><span style="font-size:medium;">            cout &lt;&lt; "If you gave me " &lt;&lt; n &lt;&lt; " toys, I would have " &lt;&lt; n + m_toys &lt;&lt; " toys total." &lt;&lt; endl;</span></strong></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><strong>        }</strong>);</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    }</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">private:</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    int m_toys;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">};</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">int main() {</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    vector&lt;int&gt; v;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    for (int i = 0; i &lt; 3; ++i) {</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">        v.push_back(i);</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    }</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    Kitty k(5);</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    k.meow(v);</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">}</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">C:\Temp&gt;cl /EHsc /nologo /W4 implicitmemberkitty.cpp &gt; NUL &amp;&amp; implicitmemberkitty</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-family:Consolas;"><span style="font-size:medium;">If you gave me 0 toys, I would have 5 toys total.</span></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-family:Consolas;"><span style="font-size:medium;">If you gave me 1 toys, I would have 6 toys total.</span></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-family:Consolas;"><span style="font-size:medium;">If you gave me 2 toys, I would have 7 toys total.</span></span></p>
<p> </p>
<p><span style="font-size:medium;font-family:Verdana;">你可以使用 <strong>[&amp;]</strong>，但它对传递是怎样进行的（默认是按值）没有影响。你不能使用 <strong>[&amp;this]</strong>。</span></p>
<p class="MsoNormal"> </p>
<p class="MsoNormal"><span style="font-size:medium;">如果你想使用一个空无的 lambda （不带参数），你可以省略整个 lambda参数声明：</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-family:Consolas;"><span style="font-size:medium;">C:\Temp&gt;type nullarykitty.cpp</span></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-family:Consolas;"><span style="font-size:medium;">#include &lt;algorithm&gt;</span></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-family:Consolas;"><span style="font-size:medium;">#include &lt;iostream&gt;</span></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-family:Consolas;"><span style="font-size:medium;">#include &lt;iterator&gt;</span></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-family:Consolas;"><span style="font-size:medium;">#include &lt;ostream&gt;</span></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-family:Consolas;"><span style="font-size:medium;">#include &lt;vector&gt;</span></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-family:Consolas;"><span style="font-size:medium;">using namespace std;</span></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-family:Consolas;"><span style="font-size:medium;"> </span></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-family:Consolas;"><span style="font-size:medium;">int main() {</span></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-family:Consolas;"><span style="font-size:medium;">    vector&lt;int&gt; v;</span></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-family:Consolas;"><span style="font-size:medium;"> </span></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-family:Consolas;"><span style="font-size:medium;">    int i = 0;</span></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-family:Consolas;"><span style="font-size:medium;"> </span></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-family:Consolas;"><span style="font-size:medium;">    generate_n(back_inserter(v), 10, <strong>[&amp;] { return i++; }</strong>);</span></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-family:Consolas;"><span style="font-size:medium;"> </span></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-family:Consolas;"><span style="font-size:medium;">    for_each(v.begin(), v.end(), [](int n) { cout &lt;&lt; n &lt;&lt; " "; });</span></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-family:Consolas;"><span style="font-size:medium;">    cout &lt;&lt; endl;</span></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-family:Consolas;"><span style="font-size:medium;"> </span></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-family:Consolas;"><span style="font-size:medium;">    cout &lt;&lt; "i: " &lt;&lt; i &lt;&lt; endl;</span></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-family:Consolas;"><span style="font-size:medium;">}</span></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-family:Consolas;"><span style="font-size:medium;"> </span></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-family:Consolas;"><span style="font-size:medium;">C:\Temp&gt;cl /EHsc /nologo /W4 nullarykitty.cpp &gt; NUL &amp;&amp; nullarykitty</span></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-family:Consolas;"><span style="font-size:medium;">0 1 2 3 4 5 6 7 8 9</span></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-family:Consolas;"><span style="font-size:medium;">i: 10</span></span></p>
<p class="MsoNormal"><span style="font-size:medium;">这比 <strong>[&amp;]() { return i++; } </strong>少两个字符。省略 lambda 参数声明是否是良好的风格是由你来决定的。</span></p>
<p class="MsoNormal"><span style="font-size:medium;">仅博一笑，这意味着下面的代码在 C++0x 中是合法的。</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-family:Consolas;"><span style="font-size:medium;">C:\Temp&gt;type nokitty.cpp</span></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-family:Consolas;"><span style="font-size:medium;">int main() {</span></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-family:Consolas;"><span style="font-size:medium;">    <strong>[](){}</strong>();</span></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-family:Consolas;"><span style="font-size:medium;">    <strong>[]{}</strong>();</span></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-family:Consolas;"><span style="font-size:medium;">}</span></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Verdana;"> </span></p>
<p class="MsoNormal"><span style="font-size:medium;">上面构建了两个什么也不做的 lambda （一个有 lambda 参数声明，一个没有）并立即调用它们（通过最后一个空括号组合）。</span></p>
<p class="MsoNormal"> </p>
<p style="font-size:12pt;text-align:center;"><span style="font-size:medium;">&lt; </span><span style="font-size:medium;"><a href="http://www.yeeyan.com/articles/view/kesalin/43288">前一页</a>   <a href="http://www.yeeyan.com/articles/view/kesalin/43571">本页</a>   </span><span style="font-size:medium;"><a href="http://www.yeeyan.com/articles/view/kesalin/43573">后一页</a> &gt; </span></p><p><a href="http://www.yeeyan.com/articles/view/kesalin/43571#newComment">添加评论</a></p>
<p><embed id="movie_rss" height="60" width="468" quality="high" bgcolor="#ffffff" name="mymovie" style="" src="http://www.yeeyan.com/files/newindexads/vancl_090622_468_rss.swf" type="application/x-shockwave-flash"/></p>
]]>
        </content>
    <feedburner:origLink>http://www.yeeyan.com/articles/view/kesalin/43571</feedburner:origLink></entry>
    <entry>
        <title>VC10中的C&amp;#43;&amp;#43;0x特性 Part 1 &amp;#40;1&amp;#41; : Lambdas，auto，以及 static_assert</title>
        <link href="http://feedproxy.google.com/~r/yeeyan_lang/~3/BCZD9_IU0LE/43288" />
        <created>2009-05-28T04:02:15+00:00</created>
        <issued>2009-05-28T04:02:15+00:00</issued>
        <modified>2009-05-28T04:02:15+00:00</modified>
        <published>2009-05-28T04:02:15+00:00</published>
        <id>tag:feed.yeeyan.com:translation/43288</id>
        <category term="科学技术" scheme="feed.yeeyan.com" label="科学技术" />
        <author>
            <name>飘飘白云</name>
            <uri>http://www.yeeyan.com/space/show/kesalin</uri>
        </author>
        <content type="html">
            <![CDATA[<p>原文作者：Visual C&#43;&#43; Team Blog<br />原文链接：<a href="http://blogs.msdn.com/vcblog/archive/2008/10/28/lambdas-auto-and-static-assert-c-0x-features-in-vc10-part-1.aspx">Lambdas, auto, and static_assert: C&#43;&#43;0x Features in VC10, Part 1</a><br/>译者：<a href="http://www.yeeyan.com/space/show/kesalin">飘飘白云</a></p><p class="MsoNormal" style="margin:0mm 0mm 0pt;text-align:center;"><span style="font-size:medium;"><strong>VC10中的C++0x特性 Part 1 (1) : Lambdas，auto，以及 static_assert</strong></span></p>
<p class="MsoNormal" style="margin:0mm 0mm 0pt;text-align:center;"> </p>
<p class="MsoNormal" style="margin:0mm 0mm 0pt;text-align:center;"><span style="font-size:medium;"><strong>来源：<a title="vcvlog" href="http://blogs.msdn.com/vcblog/archive/2008/10/28/lambdas-auto-and-static-assert-c-0x-features-in-vc10-part-1.aspx" target="_blank">vcblog</a> 翻译：<a href="http://www.cppblog.com/kesalin">飘飘白云</a> kesalin@gmail.com</strong></span></p>
<p class="MsoNormal" style="margin:0mm 0mm 0pt;"> </p>
<p class="MsoNormal" style="margin:0mm 0mm 0pt;text-align:center;"><span style="font-size:medium;">共三页： <a href="http://www.yeeyan.com/articles/view/kesalin/43288">本页</a> <a href="http://www.yeeyan.com/articles/view/kesalin/43571">第二页</a> <a href="http://www.yeeyan.com/articles/view/kesalin/43573">第三页</a></span></p>
<p class="MsoNormal" style="margin:0mm 0mm 0pt;text-align:center;"> </p>
<p><span style="font-size:medium;">Microsoft Visual Studio 2010 九月社区技术预览版 (CTP)所带的Visual C++编译器对四个C++0x语言特性</span><span style="font-size:medium;">提供了</span><span style="font-size:medium;">支持，也就是 <strong>lambdas</strong>，<strong>auto</strong>，<strong>static_assert</strong>，以及 <strong>rvalue references</strong> （右值引用，译注：后面不再对这个词进行翻译）。今天，我将详细介绍前三个特性。（很快我将贡献一整篇幅的文章来解释右值引用，仅仅是因为再在这里解释的话将会加大这篇已经很长的文章的篇幅）</span></p>
<p class="MsoNormal" style="margin:0mm 0mm 0pt;"><span style="font-size:medium;">首先，说明一些事情：</span></p>
<p class="MsoNormal" style="margin:0mm 0mm 0pt;"><span style="font-size:medium;"><br /></span></p>
<p class="MsoNormal" style="margin:0mm 0mm 0pt;"><span style="font-size:medium;">1，今天的这篇文章是由 Stephan T. Lavavej，Visual C++库的开发人员以及C, A, 与 T读者投书栏带给你们的。注意作为库的开发人员，我并没有实现这些特性。那是 Jonathan Caves，前端编译器开发者，选举标准委员会成员以及所有“忍者”（鲜为人知的高手）的成果。</span></p>
<p class="MsoNormal" style="margin:0mm 0mm 0pt;"><span style="font-size:medium;"><br /></span></p>
<p class="MsoNormal" style="margin:0mm 0mm 0pt;"><span style="font-size:medium;">2，我将 Visual C++ compiler in VS 2010 简称为 VC10 （ VS 2008 包含 VC9，VS 2005 包含 VC8，等等。 - 10 并不比 2010 简短）</span></p>
<p class="MsoNormal" style="margin:0mm 0mm 0pt;"><span style="font-size:medium;"><br /></span></p>
<p class="MsoNormal" style="margin:0mm 0mm 0pt;"><span style="font-size:medium;">3，C++0x 指的是即将到来的 C++ 标准，现在还在起草中。（C++标准委员会希望它可以在 2009 年完成，称作 C++ 09；玩笑话说如果它推迟到 2010 或者更晚的话，“x” 将是十六进制的了）。 C++ 98 和C++ 03 指的是当前的 C++ 标准。（在这里不回顾历史了， C++ 标准 2003 仅仅是最初的 C++ </span><span style="font-size:medium;">1998 </span><span style="font-size:medium;">标准 的“补丁”版，对大部分人来说可以忽略两者间的区别。C++ 03 和 C++ 0x 模样虽然看起来差不多，但完全不同）</span></p>
<p class="MsoNormal" style="margin:0mm 0mm 0pt;"><span style="font-size:medium;"><br /></span></p>
<p class="MsoNormal" style="margin:0mm 0mm 0pt;"><span style="font-size:medium;">4，我要感谢标准委员会开发出这些奇妙而有用并富有艺术的特性。他们也在以下站点上提供了重要的文档：</span></p>
<p class="MsoNormal" style="margin:0mm 0mm 0pt;"><span style="font-size:medium;"><br /></span></p>
<p class="MsoNormal" style="margin:0mm 0mm 0pt;"><span style="font-size:medium;font-family:Verdana;">C++0x 语言特性:</span></p>
<p class="MsoNormal" style="margin:0mm 0mm 0pt;"><span style="font-size:medium;font-family:Verdana;"><a href="http://open-std.org/JTC1/SC22/WG21/docs/papers/2008/n2705.html"><span style="font-size:medium;font-family:Verdana;color:#0000ff;">http://open-std.org/JTC1/SC22/WG21/docs/papers/2008/n2705.html</span></a></span></p>
<p><span style="font-size:medium;">C++0x 库特性:<br /><a href="http://open-std.org/JTC1/SC22/WG21/docs/papers/2008/n2706.html">http://open-std.org/JTC1/SC22/WG21/docs/papers/2008/n2706.html</a></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">C++0x 进行中的草案:</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><a href="http://open-std.org/JTC1/SC22/WG21/docs/papers/2008/n2798.pdf">http://open-std.org/JTC1/SC22/WG21/docs/papers/2008/n2798.pdf</a></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><br /></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">5，总是会有bug的（虽然希望不会太多），这也就是发布 CTP 版本的主要目的（让用户</span><span style="font-size:medium;">测试</span><span style="font-size:medium;">发现 bug ）。请通过 Microfsoft 把这些 bug 报告给我们。</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><br /></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">现在，让我们来审视这些特性吧！</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><strong>lambdas</strong></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><br /></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><strong>在 C++ 0x 中，“lambda 表达式”</strong><strong>隐式定义并构建不具名函数对象</strong>，这些对象就像手写函数对象一样。下面是 lambda “Hello，World”入门级的示例：</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><br /></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">C:\Temp&gt;type meow.cpp</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">#include &lt;algorithm&gt;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">#include &lt;iostream&gt;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">#include &lt;ostream&gt;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">#include &lt;vector&gt;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">using namespace std;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">int main() {</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    vector&lt;int&gt; v;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    for (int i = 0; i &lt; 10; ++i) {</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">        v.push_back(i);</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    }</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    for_each(v.begin(), v.end(), <strong>[](int n) { cout &lt;&lt; n &lt;&lt; " "; }</strong>);</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    cout &lt;&lt; endl;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">}</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">C:\Temp&gt;cl /EHsc /nologo /W4 meow.cpp &gt; NUL &amp;&amp; meow</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">0 1 2 3 4 5 6 7 8 9</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><br /></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><strong>[]</strong> 操作符是 lambda 导引符， 它告诉编译器一个 lambda 表达式开始了。 <strong>(int n) </strong>是 lambda 参数声明，它告诉编译器不具名函数对象类的函数调用操作符带有哪些参数， </span><span style="font-size:medium;font-family:Consolas;">{ cout &lt;&lt; n &lt;&lt; " "; }</span><span style="font-size:medium;font-family:Verdana;">  是复合</span><span style="font-size:medium;">声明</span><span style="font-size:medium;font-family:Verdana;">，它是不具名函数对象类</span><span style="font-size:medium;">的</span><span style="font-size:medium;font-family:Verdana;">函数调用操作</span><span style="font-size:medium;">符</span><span style="font-size:medium;font-family:Verdana;">的函数体。不具名函数对象类</span><span style="font-size:medium;">的</span><span style="font-size:medium;font-family:Verdana;">函数调用操作</span><span style="font-size:medium;">符</span><span style="font-size:medium;font-family:Verdana;">默认返回 <strong>void</strong>。</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><br /></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">这样，C++0x 在内部将它转换成如你在C++ 98 下编写的一样代码： </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Verdana;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">C:\Temp&gt;type meow98.cpp</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">#include &lt;algorithm&gt;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">#include &lt;iostream&gt;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">#include &lt;ostream&gt;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">#include &lt;vector&gt;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">using namespace std;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><strong>struct LambdaFunctor {</strong></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><strong>    void operator()(int n) const {</strong></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><strong>        cout &lt;&lt; n &lt;&lt; " ";</strong></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><strong>    }</strong></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><strong>};</strong></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">int main() {</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    vector&lt;int&gt; v;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    for (int i = 0; i &lt; 10; ++i) {</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">        v.push_back(i);</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    }</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    for_each(v.begin(), v.end(), <strong>LambdaFunctor()</strong>);</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    cout &lt;&lt; endl;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">}</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">C:\Temp&gt;cl /EHsc /nologo /W4 meow98.cpp &gt; NUL &amp;&amp; meow98</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">0 1 2 3 4 5 6 7 8 9</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Verdana;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">现在我将不再累述</span><span style="font-size:medium;">类似</span><span style="font-size:medium;">“不具名函数对象类</span><span style="font-size:medium;">的</span><span style="font-size:medium;">函数调用操作符默认返回 <strong>void</strong>”这样的话，开始换用“lambda 函数返回 <strong>void</strong>”的说法，但是记住 lambda 表达式做了些什么是很重要的，那就是：定义类并构建对象。</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><br /></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">当然，lambda 的复合声明部分（函数体部分）可以包含多个声明语句，譬如：</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><br /></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">C:\Temp&gt;type multimeow.cpp</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">#include &lt;algorithm&gt;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">#include &lt;iostream&gt;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">#include &lt;ostream&gt;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">#include &lt;vector&gt;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">using namespace std;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">int main() {</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    vector&lt;int&gt; v;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    for (int i = 0; i &lt; 10; ++i) {</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">        v.push_back(i);</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    }</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    for_each(v.begin(), v.end(), <strong>[](int n) {</strong></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><strong>        cout &lt;&lt; n;</strong></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><strong> </strong></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><strong>        if (n % 2 == 0) {</strong></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><strong>            cout &lt;&lt; " even ";</strong></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><strong>        } else {</strong></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><strong>            cout &lt;&lt; " odd ";</strong></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><strong>        }</strong></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><strong>    }</strong>);</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    cout &lt;&lt; endl;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">}</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">C:\Temp&gt;cl /EHsc /nologo /W4 multimeow.cpp &gt; NUL &amp;&amp; multimeow</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">0 even 1 odd 2 even 3 odd 4 even 5 odd 6 even 7 odd 8 even 9 odd</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Verdana;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Verdana;">lambda 函数也并不总是必须返回 <strong>void</strong>。如果 lambda 的复合声明语句像是这样的 <strong>{ return <em>expression</em>; }</strong> ，那么 lambda 的返回类型就会自动地被推断成 <em>expression</em> 的类型<em>。</em></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><br /></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">C:\Temp&gt;type cubicmeow.cpp</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">#include &lt;algorithm&gt;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">#include &lt;deque&gt;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">#include &lt;iostream&gt;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">#include &lt;iterator&gt;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">#include &lt;ostream&gt;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">#include &lt;vector&gt;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">using namespace std;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">int main() {</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    vector&lt;int&gt; v;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    for (int i = 0; i &lt; 10; ++i) {</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">        v.push_back(i);</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    }</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    deque&lt;int&gt; d;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    transform(v.begin(), v.end(), front_inserter(d), <strong>[](int n) { return n * n * n; }</strong>);</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    for_each(d.begin(), d.end(), [](int n) { cout &lt;&lt; n &lt;&lt; " "; });</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    cout &lt;&lt; endl;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">}</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">C:\Temp&gt;cl /EHsc /nologo /W4 cubicmeow.cpp &gt; NUL &amp;&amp; cubicmeow</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">729 512 343 216 125 64 27 8 1 0</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Verdana;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">在这里,  <strong>n * n * n</strong> 的类型是 <strong>int</strong>，所以 lambda 函数返回 <strong>int</strong>。</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><br /></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">有着复杂复合声明语句的 lambda 函数不会自动推断返回类型，你必须显式指定返回类型。</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><br /></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">C:\Temp&gt;type returnmeow.cpp</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">#include &lt;algorithm&gt;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">#include &lt;deque&gt;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">#include &lt;iostream&gt;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">#include &lt;iterator&gt;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">#include &lt;ostream&gt;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">#include &lt;vector&gt;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">using namespace std;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">int main() {</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    vector&lt;int&gt; v;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    for (int i = 0; i &lt; 10; ++i) {</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">        v.push_back(i);</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    }</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    deque&lt;double&gt; d;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    transform(v.begin(), v.end(), front_inserter(d), <strong>[](int n) -&gt; double {</strong></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><strong>        if (n % 2 == 0) {</strong></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><strong>            return n * n * n;</strong></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><strong>        } else {</strong></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><strong>            return n / 2.0;</strong></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><strong>        }</strong></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><strong>    }</strong>);</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    for_each(d.begin(), d.end(), [](double x) { cout &lt;&lt; x &lt;&lt; " "; });</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    cout &lt;&lt; endl;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">}</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">C:\Temp&gt;cl /EHsc /nologo /W4 returnmeow.cpp &gt; NUL &amp;&amp; returnmeow</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">4.5 512 3.5 216 2.5 64 1.5 8 0.5 0</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Verdana;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><strong>-&gt; double</strong> 是可选的 lambda 返回类型从句。为什么它不放在左边（译注：返回类型一般在函数左边声明），就像程序员一直以来在C函数中做的那样？因为那样的话 lambda 导引符 <strong>[]</strong> 就不会第一个出现了，而正是它告诉编译器一个 lambda 函数开始了。（核心工作组最擅长解决这样的问题；尝试猜测C++ 中一个给定的概念是否是可被解析的会让我头疼。）</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><br /></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Verdana;">如果忘记了指定 lambda返回类型从句，编译器就会抱怨每一个返回语句：</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;font-family:Verdana;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">C:\Temp&gt;cl /EHsc /nologo /W4 borkedreturnmeow.cpp</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">borkedreturnmeow.cpp</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">borkedreturnmeow.cpp(20) : <strong>error C3499: a lambda that has been specified to have a void return type cannot return a value</strong></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">borkedreturnmeow.cpp(22) : <strong>error C3499: a lambda that has been specified to have a void return type cannot return a value</strong></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><br /></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><br /></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><span lang="zh-cn" xml:lang="zh-cn">到目前</span><span lang="zh-cn" xml:lang="zh-cn">为</span><span lang="zh-cn" xml:lang="zh-cn">止我所介</span><span lang="zh-cn" xml:lang="zh-cn">绍</span><span lang="zh-cn" xml:lang="zh-cn">的</span><span lang="en" xml:lang="en"> lambda </span><span lang="zh-cn" xml:lang="zh-cn">都是无状</span><span lang="zh-cn" xml:lang="zh-cn">态</span><span lang="zh-cn" xml:lang="zh-cn">的：它</span><span lang="zh-cn" xml:lang="zh-cn">们</span><span lang="zh-cn" xml:lang="zh-cn">不包含数据成</span><span lang="zh-cn" xml:lang="zh-cn">员</span><span lang="zh-cn" xml:lang="zh-cn">。你也可以有有状</span><span lang="zh-cn" xml:lang="zh-cn">态</span><span lang="zh-cn" xml:lang="zh-cn">的</span><span lang="en" xml:lang="en"> lambda</span><span lang="zh-cn" xml:lang="zh-cn">，</span><span lang="zh-cn" xml:lang="zh-cn">这</span><span lang="zh-cn" xml:lang="zh-cn">是通</span><span lang="zh-cn" xml:lang="zh-cn">过</span><span lang="en" xml:lang="en">“</span><span lang="zh-cn" xml:lang="zh-cn">传递</span><span lang="en" xml:lang="en">”</span><span lang="zh-cn" xml:lang="zh-cn">（原文用</span></span><span style="font-size:medium;">加引号的 capturing 这个词，在这里我翻译成传递似乎不太妥，故我都加括号引用原文，下同</span><span style="font-size:medium;"><span lang="zh-cn" xml:lang="zh-cn">）局部</span><span lang="zh-cn" xml:lang="zh-cn">变</span><span lang="zh-cn" xml:lang="zh-cn">量来</span><span lang="zh-cn" xml:lang="zh-cn">实现</span><span lang="zh-cn" xml:lang="zh-cn">的。</span><span lang="zh-cn" xml:lang="zh-cn">空的</span><span lang="en" xml:lang="en"> lambda </span><span lang="zh-cn" xml:lang="zh-cn">导</span><span lang="zh-cn" xml:lang="zh-cn">引符</span><span lang="en" xml:lang="en"> <strong>[]</strong> </span><span lang="zh-cn" xml:lang="zh-cn">意味着</span><span lang="en" xml:lang="en">“</span><span lang="zh-cn" xml:lang="zh-cn">一个无状</span><span lang="zh-cn" xml:lang="zh-cn">态</span><span lang="zh-cn" xml:lang="zh-cn">的</span><span lang="en" xml:lang="en"> lambda”</span><span lang="zh-cn" xml:lang="zh-cn">，但在</span><span lang="en" xml:lang="en"> lambda </span><span lang="zh-cn" xml:lang="zh-cn">导</span><span lang="zh-cn" xml:lang="zh-cn">引符</span><span lang="en" xml:lang="en"> <strong>[] </strong></span><span lang="zh-cn" xml:lang="zh-cn">中你可以指定</span><em><span lang="en" xml:lang="en"> capture-list </span></em><span lang="zh-cn" xml:lang="zh-cn">：</span></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">C:\Temp&gt;type capturekittybyvalue.cpp</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">#include &lt;algorithm&gt;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">#include &lt;iostream&gt;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">#include &lt;ostream&gt;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">#include &lt;vector&gt;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">using namespace std;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">int main() {</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    vector&lt;int&gt; v;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    for (int i = 0; i &lt; 10; ++i) {</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">        v.push_back(i);</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    }</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    int x = 0;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    int y = 0;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    // op&gt;&gt;() leaves newlines on the input stream,</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    // which can be extremely confusing. I recommend</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    // avoiding it, and instead using non-member</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    // getline(cin, str) to read whole lines and</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    // then parse them. But in the interests of</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    // brevity, I'll use evil op&gt;&gt;():</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    cout &lt;&lt; "Input: ";</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    cin &gt;&gt; x &gt;&gt; y;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    v.erase(remove_if(v.begin(), v.end(), <strong>[x, y](int n) { return x &lt; n &amp;&amp; n &lt; y; }</strong>), v.end());</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    for_each(v.begin(), v.end(), [](int n) { cout &lt;&lt; n &lt;&lt; " "; });</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    cout &lt;&lt; endl;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">}</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">C:\Temp&gt;cl /EHsc /nologo /W4 capturekittybyvalue.cpp &gt; NUL &amp;&amp; capturekittybyvalue</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">Input: 4 7</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">0 1 2 3 4 7 8 9</span></p>
<p class="MsoNormal" align="left"><span style="font-size:medium;"><span lang="zh-cn" xml:lang="zh-cn">如果你忘</span><span lang="zh-cn" xml:lang="zh-cn">记</span><span lang="zh-cn" xml:lang="zh-cn">了</span><em><span lang="en" xml:lang="en">capture-list</span></em><span lang="zh-cn" xml:lang="zh-cn">，</span><span lang="zh-cn" xml:lang="zh-cn">编译</span><span lang="zh-cn" xml:lang="zh-cn">器就会抱怨：</span></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">C:\Temp&gt;cl /EHsc /nologo /W4 borkedcapturekittybyvalue.cpp</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">borkedcapturekittybyvalue.cpp</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">borkedcapturekittybyvalue.cpp(27) : <strong>error C3493: 'x' cannot be implicitly captured as no default capture mode has been specified</strong></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">borkedcapturekittybyvalue.cpp(27) : <strong>error C3493: 'y' cannot be implicitly captured as no default capture mode has been specified</strong></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><br /></span></p>
<p><span style="font-size:medium;"><span lang="zh-cn" xml:lang="zh-cn">（我很快就会解</span><span lang="zh-cn" xml:lang="zh-cn">释</span><span lang="zh-cn" xml:lang="zh-cn">默</span><span lang="zh-cn" xml:lang="zh-cn">认</span><span lang="zh-cn" xml:lang="zh-cn">的传递</span><span lang="zh-cn" xml:lang="zh-cn">（</span><span lang="en" xml:lang="en">capture</span><span lang="zh-cn" xml:lang="zh-cn">））</span></span></p>
<p><span style="font-size:medium;">记着，lambda 表达式隐式地定义了一个不具名函数对象类。复合声明语句<strong> { return x &lt; n &amp;&amp; n &lt; y; } </strong>在这个类中被当作函数调用操作符的函数体。虽然从词法结构上看复合声明语句是在 <strong>main()</strong> 块之内，但在概念上它是在 <strong>main() </strong>块之外的，因此如果不传递</span><span style="font-size:medium;"><span lang="zh-cn" xml:lang="zh-cn">（</span><span lang="en" xml:lang="en">capture</span><span lang="zh-cn" xml:lang="zh-cn">）</span></span><span style="font-size:medium;">到 lambda 中去，就</span><span style="font-size:medium;">不能</span><span style="font-size:medium;">在其中使用来自<strong>main()</strong> 中的局部变量。</span></p>
<p><span style="font-size:medium;">上面的代码在内部被翻译成：</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">C:\Temp&gt;type capturekittybyvalue98.cpp</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">#include &lt;algorithm&gt;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">#include &lt;iostream&gt;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">#include &lt;iterator&gt;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">#include &lt;ostream&gt;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">#include &lt;vector&gt;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">using namespace std;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><strong>class LambdaFunctor {</strong></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><strong>public:</strong></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><strong>    LambdaFunctor(int a, int b) : m_a(a), m_b(b) { }</strong></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><strong> </strong></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><strong>    bool operator()(int n) const { return m_a &lt; n &amp;&amp; n &lt; m_b; }</strong></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><strong> </strong></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><strong>private:</strong></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><strong>    int m_a;</strong></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><strong>    int m_b;</strong></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><strong>};</strong></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">int main() {</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    vector&lt;int&gt; v;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    for (int i = 0; i &lt; 10; ++i) {</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">        v.push_back(i);</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    }</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    int x = 0;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    int y = 0;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    cout &lt;&lt; "Input: ";</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    cin &gt;&gt; x &gt;&gt; y; // EVIL!</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    v.erase(remove_if(v.begin(), v.end(), <strong>LambdaFunctor(x, y)</strong>), v.end());</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    copy(v.begin(), v.end(), ostream_iterator&lt;int&gt;(cout, " "));</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    cout &lt;&lt; endl;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">}</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">C:\Temp&gt;cl /EHsc /nologo /W4 capturekittybyvalue98.cpp &gt; NUL &amp;&amp; capturekittybyvalue98</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">Input: 4 7</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">0 1 2 3 4 7 8 9</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><br /></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">在这里你可以清楚地看到</span><span style="font-size:medium;">是</span><span style="font-size:medium;">“按值”</span><span style="font-size:medium;">传递（captures）</span><span style="font-size:medium;">的。函数对象存储了局部变量的拷贝。这就使得函数对象可以比通过传递（capture）来创建它们的局部变量有更长的生命期。但是，要注意：（a）在 lambda 中不能修改通过传递（capture）获得的拷贝，因为默认情况下函数调用操作符是 <strong>const </strong>属性的，（b）一些对象的拷贝开销是昂贵的，（c）局部变量的更新不会反应到</span><span style="font-size:medium;">通过</span><span style="font-size:medium;">传递（capture）获得的拷贝</span><span style="font-size:medium;">（在语义上它们是原始值）。很快我就会解释如有需要应该如何来处理以上情况。</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><br /></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">但是首先，你可以“按值传递（capture）任何东西”，而不用特别指明每一个你想要传递(capture)的局部变量。其语法是使用这种形式的 lambda 导引符<strong> [=] </strong>（默认传递（</span><span style="font-size:medium;"><em>capture-default</em></span><span style="font-size:medium;">） <strong>=</strong> 应该可以让你想起赋值或者拷贝初始化 Foo foo = bar; 虽然这里的拷贝实际上是直接初始化（通过初始化列表进行赋值），就像上面的 m_a(a)）。</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><br /></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">C:\Temp&gt;type defaultcapturekittybyvalue.cpp</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">#include &lt;algorithm&gt;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">#include &lt;iostream&gt;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">#include &lt;ostream&gt;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">#include &lt;vector&gt;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">using namespace std;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">int main() {</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    vector&lt;int&gt; v;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    for (int i = 0; i &lt; 10; ++i) {</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">        v.push_back(i);</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    }</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    int x = 0;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    int y = 0;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    cout &lt;&lt; "Input: ";</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    cin &gt;&gt; x &gt;&gt; y; // EVIL!</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    v.erase(remove_if(v.begin(), v.end(), <strong>[=](int n) { return x &lt; n &amp;&amp; n &lt; y; }</strong>), v.end());</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    for_each(v.begin(), v.end(), [](int n) { cout &lt;&lt; n &lt;&lt; " "; });</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">    cout &lt;&lt; endl;</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">}</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"> </span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">C:\Temp&gt;cl /EHsc /nologo /W4 defaultcapturekittybyvalue.cpp &gt; NUL &amp;&amp; defaultcapturekittybyvalue</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">Input: 4 7</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">0 1 2 3 4 7 8 9</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;"><br /></span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"><span style="font-size:medium;">当编译器看到 lambda 中的 x 和 y， 就会从 main() 中按值传递（capture）。</span></p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"> </p>
<p class="MsoNormal" style="margin:0in 0in 0pt;"> </p>
<p class="MsoNormal" style="margin:0in 0in 0pt;text-align:center;"><span style="font-size:medium;"> &lt; </span><span style="font-size:medium;"><a href="http://www.yeeyan.com/articles/view/kesalin/43288">本页</a>   <a href="http://www.yeeyan.com/articles/view/kesalin/43571">下页</a>   </span><span style="font-size:medium;"><a href="http://www.yeeyan.com/articles/view/kesalin/43573">下下一页</a> &gt; <br /></span></p>
<p> </p><p><a href="http://www.yeeyan.com/articles/view/kesalin/43288#newComment">添加评论</a></p>
<p><embed id="movie_rss" height="60" width="468" quality="high" bgcolor="#ffffff" name="mymovie" style="" src="http://www.yeeyan.com/files/newindexads/vancl_090622_468_rss.swf" type="application/x-shockwave-flash"/></p>
]]>
        </content>
    <feedburner:origLink>http://www.yeeyan.com/articles/view/kesalin/43288</feedburner:origLink></entry>
    <entry>
        <title>RSS 2.0规范</title>
        <link href="http://feedproxy.google.com/~r/yeeyan_lang/~3/wbdSyffcm4Q/34444" />
        <created>2009-05-13T02:22:01+00:00</created>
        <issued>2009-05-13T02:22:01+00:00</issued>
        <modified>2009-05-13T02:22:01+00:00</modified>
        <published>2009-05-13T02:22:01+00:00</published>
        <id>tag:feed.yeeyan.com:translation/34444</id>
        <category term="电脑网络" scheme="feed.yeeyan.com" label="电脑网络" />
        <author>
            <name>RJmicheal</name>
            <uri>http://www.yeeyan.com/space/show/75374</uri>
        </author>
        <content type="html">
            <![CDATA[<p>原文作者：Harvard Law<br />原文链接：<a href="http://blogs.law.harvard.edu/tech/rss">RSS 2.0 Specification</a><br/>译者：<a href="http://www.yeeyan.com/space/show/75374">RJmicheal</a></p><p class="MsoNormal" style="margin:11.25pt 0cm;text-align:center;" align="center"><strong><span style="font-size:19.5pt;" lang="en-us" xml:lang="en-us"><span style="font-family:'Times New Roman';">RSS 2.0</span></span></strong><strong><span style="font-size:19.5pt;font-family:'宋体';">规范</span></strong><strong><span style="font-family:'宋体';" lang="en-us" xml:lang="en-us"></span></strong></p>
<p class="MsoNormal" style="margin:0cm 0cm 0pt;text-align:left;" align="left"><span style="font-size:medium;"><span style="font-family:'宋体';" lang="en-us" xml:lang="en-us">Archivist's Note: This is version 2.0.10 of the RSS 2.0 specification, published by the RSS Advisory Board on Oct. 15, 2007.</span><span style="font-family:'宋体';">档管人员</span><span style="font-family:'宋体';">注释</span><span style="font-family:'宋体';">：这是<span lang="en-us" xml:lang="en-us">RSS 2.0</span>规范的<span lang="en-us" xml:lang="en-us">2.0.10</span>版本<span lang="en-us" xml:lang="en-us">,</span>在<span lang="en-us" xml:lang="en-us">2007</span>年<span lang="en-us" xml:lang="en-us">10</span>月<span lang="en-us" xml:lang="en-us">15</span>日由<span lang="en-us" xml:lang="en-us">RSS</span>顾问委员会出版。 <span lang="en-us" xml:lang="en-us">The current version of the RSS spec will always be available at <a href="http://203.208.33.132/translate_c?hl=zh-CN&amp;sl=en&amp;u=http://www.rssboard.org/rss-specification&amp;prev=/search%3Fq%3DArchivist%2527s%2BNote:%2BThis%2Bis%2Bversion%2B2.0.10%2Bof%2Bthe%2BRSS%2B2.0%26hl%3Dzh-CN%26newwindow%3D1&amp;usg=ALkJrhgDcCDDY6Rz7zQg4_X-fBi-XkJFPw"><span>this link</span></a> , all changes have been <a href="http://203.208.33.132/translate_c?hl=zh-CN&amp;sl=en&amp;u=http://www.rssboard.org/rss-change-notes&amp;prev=/search%3Fq%3DArchivist%2527s%2BNote:%2BThis%2Bis%2Bversion%2B2.0.10%2Bof%2Bthe%2BRSS%2B2.0%26hl%3Dzh-CN%26newwindow%3D1&amp;usg=ALkJrhhcqVy_W8b9JjFG2LNcX0XwsUAHLw"><span>logged</span></a> and <a href="http://203.208.33.132/translate_c?hl=zh-CN&amp;sl=en&amp;u=http://www.rssboard.org/rss-history&amp;prev=/search%3Fq%3DArchivist%2527s%2BNote:%2BThis%2Bis%2Bversion%2B2.0.10%2Bof%2Bthe%2BRSS%2B2.0%26hl%3Dzh-CN%26newwindow%3D1&amp;usg=ALkJrhjPAwSJV3GjLgOB4Y7ri_Bp1zrMkA"><span>other revisions</span></a> have been archived.</span>目前的<span lang="en-us" xml:lang="en-us">RSS</span>规范版本将在这个环节上永远有效，所有的变更已存入数据和其他的修订已被封存。<span lang="en-us" xml:lang="en-us"></span></span></span></p>
<p class="MsoNormal" style="margin:0cm 0cm 0pt;text-align:left;" align="left"><strong><span style="font-size:12pt;font-family:'宋体';" lang="en-us" xml:lang="en-us">Contents</span></strong><strong><span style="font-size:12pt;font-family:'宋体';">目录 <span lang="en-us" xml:lang="en-us"></span></span></strong></p>
<ul type="disc"><li class="MsoNormal" style="margin:0cm 0cm 0pt;text-align:left;"><span style="font-size:12pt;font-family:'宋体';" lang="en-us" xml:lang="en-us"><a href="http://203.208.33.132/translate_c?hl=zh-CN&amp;sl=en&amp;u=http://www.rssboard.org/rss-specification&amp;prev=/search%3Fq%3DArchivist%2527s%2BNote:%2BThis%2Bis%2Bversion%2B2.0.10%2Bof%2Bthe%2BRSS%2B2.0%26hl%3Dzh-CN%26newwindow%3D1&amp;usg=ALkJrhgDcCDDY6Rz7zQg4_X-fBi-XkJFPw#whatIsRss"><span style="text-decoration:none;">What is RSS?</span></a></span><span style="font-size:12pt;font-family:'宋体';" lang="en-us" xml:lang="en-us"></span><span style="font-family:'宋体';"><span style="font-size:medium;">什么是<span lang="en-us" xml:lang="en-us">RSS </span>？<span lang="en-us" xml:lang="en-us"></span></span></span></li>
<li class="MsoNormal" style="margin:0cm 0cm 0pt;text-align:left;"><span style="font-family:'宋体';" lang="en-us" xml:lang="en-us"><a href="http://203.208.33.132/translate_c?hl=zh-CN&amp;sl=en&amp;u=http://www.rssboard.org/rss-specification&amp;prev=/search%3Fq%3DArchivist%2527s%2BNote:%2BThis%2Bis%2Bversion%2B2.0.10%2Bof%2Bthe%2BRSS%2B2.0%26hl%3Dzh-CN%26newwindow%3D1&amp;usg=ALkJrhgDcCDDY6Rz7zQg4_X-fBi-XkJFPw#sampleFiles"><span style="text-decoration:none;"><span style="font-size:medium;">Sample files</span></span></a></span><span style="font-size:medium;"><span style="font-family:'宋体';" lang="en-us" xml:lang="en-us"></span><span style="font-family:'宋体';">样本文件<span lang="en-us" xml:lang="en-us"></span></span></span></li>
<li class="MsoNormal" style="margin:0cm 0cm 0pt;text-align:left;"><span style="font-family:'宋体';" lang="en-us" xml:lang="en-us"><a href="http://203.208.33.132/translate_c?hl=zh-CN&amp;sl=en&amp;u=http://www.rssboard.org/rss-specification&amp;prev=/search%3Fq%3DArchivist%2527s%2BNote:%2BThis%2Bis%2Bversion%2B2.0.10%2Bof%2Bthe%2BRSS%2B2.0%26hl%3Dzh-CN%26newwindow%3D1&amp;usg=ALkJrhgDcCDDY6Rz7zQg4_X-fBi-XkJFPw#aboutThisDocument"><span style="text-decoration:none;"><span style="font-size:medium;">About this document</span></span></a></span><span style="font-size:medium;"><span style="font-family:'宋体';" lang="en-us" xml:lang="en-us"></span><span style="font-family:'宋体';">关于文档<span lang="en-us" xml:lang="en-us"><a href="http://203.208.33.132/translate_c?hl=zh-CN&amp;sl=en&amp;u=http://www.rssboard.org/rss-specification&amp;prev=/search%3Fq%3DArchivist%2527s%2BNote:%2BThis%2Bis%2Bversion%2B2.0.10%2Bof%2Bthe%2BRSS%2B2.0%26hl%3Dzh-CN%26newwindow%3D1&amp;usg=ALkJrhgDcCDDY6Rz7zQg4_X-fBi-XkJFPw#aboutThisDocument"></a> </span></span></span></li>
<li class="MsoNormal" style="margin:0cm 0cm 0pt;text-align:left;"><span style="font-family:'宋体';" lang="en-us" xml:lang="en-us"><a href="http://203.208.33.132/translate_c?hl=zh-CN&amp;sl=en&amp;u=http://www.rssboard.org/rss-specification&amp;prev=/search%3Fq%3DArchivist%2527s%2BNote:%2BThis%2Bis%2Bversion%2B2.0.10%2Bof%2Bthe%2BRSS%2B2.0%26hl%3Dzh-CN%26newwindow%3D1&amp;usg=ALkJrhgDcCDDY6Rz7zQg4_X-fBi-XkJFPw#requiredChannelElements"><span style="text-decoration:none;"><span style="font-size:medium;">Required channel elements</span></span></a></span><span style="font-size:medium;"><span style="font-family:'宋体';" lang="en-us" xml:lang="en-us"></span><span style="font-family:'宋体';">必须的频道元素<span lang="en-us" xml:lang="en-us"></span></span></span></li>
<li class="MsoNormal" style="margin:0cm 0cm 0pt;text-align:left;"><span style="font-family:'宋体';" lang="en-us" xml:lang="en-us"><a href="http://203.208.33.132/translate_c?hl=zh-CN&amp;sl=en&amp;u=http://www.rssboard.org/rss-specification&amp;prev=/search%3Fq%3DArchivist%2527s%2BNote:%2BThis%2Bis%2Bversion%2B2.0.10%2Bof%2Bthe%2BRSS%2B2.0%26hl%3Dzh-CN%26newwindow%3D1&amp;usg=ALkJrhgDcCDDY6Rz7zQg4_X-fBi-XkJFPw#optionalChannelElements"><span style="text-decoration:none;"><span style="font-size:medium;">Optional channel elements</span></span></a></span><span style="font-size:medium;"><span style="font-family:'宋体';" lang="en-us" xml:lang="en-us"></span><span style="font-family:'宋体';">可选的频道元素<span lang="en-us" xml:lang="en-us"></span></span></span></li>
<li class="MsoNormal" style="margin:0cm 0cm 0pt;text-align:left;"><span style="font-family:'宋体';" lang="en-us" xml:lang="en-us"><a href="http://203.208.33.132/translate_c?hl=zh-CN&amp;sl=en&amp;u=http://www.rssboard.org/rss-specification&amp;prev=/search%3Fq%3DArchivist%2527s%2BNote:%2BThis%2Bis%2Bversion%2B2.0.10%2Bof%2Bthe%2BRSS%2B2.0%26hl%3Dzh-CN%26newwindow%3D1&amp;usg=ALkJrhgDcCDDY6Rz7zQg4_X-fBi-XkJFPw#hrelementsOfLtitemgt"><span style="text-decoration:none;"><span style="font-size:medium;">Elements of &lt;item&gt;</span></span></a></span><span style="font-size:medium;"><span style="font-family:'宋体';" lang="en-us" xml:lang="en-us"> &lt;item&gt;</span><span style="font-family:'宋体';">的元素<span lang="en-us" xml:lang="en-us"></span></span></span></li>
<li class="MsoNormal" style="margin:0cm 0cm 0pt;text-align:left;"><span style="font-family:'宋体';" lang="en-us" xml:lang="en-us"><a href="http://203.208.33.132/translate_c?hl=zh-CN&amp;sl=en&amp;u=http://www.rssboard.org/rss-specification&amp;prev=/search%3Fq%3DArchivist%2527s%2BNote:%2BThis%2Bis%2Bversion%2B2.0.10%2Bof%2Bthe%2BRSS%2B2.0%26hl%3Dzh-CN%26newwindow%3D1&amp;usg=ALkJrhgDcCDDY6Rz7zQg4_X-fBi-XkJFPw#comments"><span style="text-decoration:none;"><span style="font-size:medium;">Comments</span></span></a></span><span style="font-size:medium;"><span style="font-family:'宋体';" lang="en-us" xml:lang="en-us"></span><span style="font-family:'宋体';">注释<span lang="en-us" xml:lang="en-us"></span></span></span></li>
<li class="MsoNormal" style="margin:0cm 0cm 0pt;text-align:left;"><span style="font-family:'宋体';" lang="en-us" xml:lang="en-us"><a href="http://203.208.33.132/translate_c?hl=zh-CN&amp;sl=en&amp;u=http://www.rssboard.org/rss-specification&amp;prev=/search%3Fq%3DArchivist%2527s%2BNote:%2BThis%2Bis%2Bversion%2B2.0.10%2Bof%2Bthe%2BRSS%2B2.0%26hl%3Dzh-CN%26newwindow%3D1&amp;usg=ALkJrhgDcCDDY6Rz7zQg4_X-fBi-XkJFPw#extendingRss"><span style="text-decoration:none;"><span style="font-size:medium;">Extending RSS</span></span></a></span><span style="font-size:medium;"><span style="font-family:'宋体';" lang="en-us" xml:lang="en-us"> RSS</span><span style="font-family:'宋体';">的扩展<span lang="en-us" xml:lang="en-us"></span></span></span></li>
<li class="MsoNormal" style="margin:0cm 0cm 0pt;text-align:left;"><span style="font-family:'宋体';" lang="en-us" xml:lang="en-us"><a href="http://203.208.33.132/translate_c?hl=zh-CN&amp;sl=en&amp;u=http://www.rssboard.org/rss-specification&amp;prev=/search%3Fq%3DArchivist%2527s%2BNote:%2BThis%2Bis%2Bversion%2B2.0.10%2Bof%2Bthe%2BRSS%2B2.0%26hl%3Dzh-CN%26newwindow%3D1&amp;usg=ALkJrhgDcCDDY6Rz7zQg4_X-fBi-XkJFPw#roadmap"><span style="text-decoration:none;"><span style="font-size:medium;">Roadmap</span></span></a></span><span style="font-size:medium;"><span style="font-family:'宋体';" lang="en-us" xml:lang="en-us"></span><span style="font-family:'宋体';">展望 <span lang="en-us" xml:lang="en-us"></span></span></span></li>
<li class="MsoNormal" style="margin:0cm 0cm 0pt;text-align:left;"><span style="font-family:'宋体';" lang="en-us" xml:lang="en-us"><a href="http://203.208.33.132/translate_c?hl=zh-CN&amp;sl=en&amp;u=http://www.rssboard.org/rss-specification&amp;prev=/search%3Fq%3DArchivist%2527s%2BNote:%2BThis%2Bis%2Bversion%2B2.0.10%2Bof%2Bthe%2BRSS%2B2.0%26hl%3Dzh-CN%26newwindow%3D1&amp;usg=ALkJrhgDcCDDY6Rz7zQg4_X-fBi-XkJFPw#licenseAndAuthorship"><span style="text-decoration:none;"><span style="font-size:medium;">License and authorship</span></span></a></span><span style="font-size:medium;"><span style="font-family:'宋体';" lang="en-us" xml:lang="en-us"></span><span style="font-family:'宋体';">许可协议和作者<span lang="en-us" xml:lang="en-us"></span></span></span></li>
</ul><p class="MsoNormal" style="margin:11.25pt 0cm 11.25pt 21pt;text-indent:-21pt;line-height:18pt;text-align:left;" align="left"><span style="font-size:medium;"><span style="font-family:'宋体';" lang="en-us" xml:lang="en-us"><span>一、</span></span><strong><span style="font-family:'宋体';">什么是<span lang="en-us" xml:lang="en-us"> RSS?<a href="http://www.sssdf.com/show.jsp?categoryid=2&amp;id=00012#whatIsRss" target="_blank"></a></span></span></strong><span style="font-family:'宋体';" lang="en-us" xml:lang="en-us"></span></span></p>
<p class="MsoNormal" style="margin:11.25pt 0cm;line-height:18pt;text-align:left;" align="left"><span style="font-family:'宋体';" lang="en-us" xml:lang="en-us"><span style="font-size:medium;">RSS </span></span><span style="font-family:'宋体';"><span style="font-size:medium;">是一种站点内容聚合的格式。</span><span lang="en-us" xml:lang="en-us"><br /></span><span style="font-size:medium;">它的名字是<span lang="en-us" xml:lang="en-us">Really Simple Syndication </span>的的简写。</span><span lang="en-us" xml:lang="en-us"><br /><span style="font-size:medium;">RSS</span></span><span style="font-size:medium;">是<span lang="en-us" xml:lang="en-us">XML</span>的一种。所有的<span lang="en-us" xml:lang="en-us">RSS</span>文档都遵循 <span lang="en-us" xml:lang="en-us">XML 1.0</span>规范<span lang="en-us" xml:lang="en-us">, </span>该规范发布在<span lang="en-us" xml:lang="en-us">W3C</span>网站上。<span lang="en-us" xml:lang="en-us"></span></span></span></p>
<p class="MsoNormal" style="margin:11.25pt 0cm;line-height:18pt;text-align:left;" align="left"><span style="font-family:'宋体';"><span style="font-size:medium;">这里是<span lang="en-us" xml:lang="en-us">RSS</span>版本历史的一个概要。</span><span lang="en-us" xml:lang="en-us"><br /></span><span style="font-size:medium;">在一个<span lang="en-us" xml:lang="en-us">RSS</span>文档中，最外层是一个<span lang="en-us" xml:lang="en-us">&lt;rss&gt;</span>元素，这个元素必须规定<span lang="en-us" xml:lang="en-us">version</span>属性，该属性明确了本文档遵从何种<span lang="en-us" xml:lang="en-us">RSS</span>版本规范。如果一个<span lang="en-us" xml:lang="en-us">RSS</span>文档以这个规范来表示，那么它的<span lang="en-us" xml:lang="en-us">version</span>属性就必须是<span lang="en-us" xml:lang="en-us">2.0</span>。<span lang="en-us" xml:lang="en-us"></span></span></span></p>
<p class="MsoNormal" style="margin:11.25pt 0cm;line-height:18pt;text-align:left;" align="left"><span style="font-size:medium;"><span style="font-family:'宋体';" lang="en-us" xml:lang="en-us">&lt;rss&gt;</span><span style="font-family:'宋体';">元素只有一个子元素<span lang="en-us" xml:lang="en-us">&lt;channel&gt;</span>，包含了关于这个频道<span lang="en-us" xml:lang="en-us">(</span>元数据<span lang="en-us" xml:lang="en-us">)</span>和它的内容的一些信息。<span lang="en-us" xml:lang="en-us"></span></span></span></p>
<p class="MsoNormal" style="margin:11.25pt 0cm 11.25pt 21pt;text-indent:-21pt;line-height:18pt;text-align:left;" align="left"><span style="font-size:medium;"><span style="font-family:'宋体';" lang="en-us" xml:lang="en-us"><span>二、</span></span><strong><span style="font-family:'宋体';">样本文件<span lang="en-us" xml:lang="en-us"><a href="http://www.sssdf.com/show.jsp?categoryid=2&amp;id=00012#sampleFiles" target="_blank"></a></span></span></strong><span style="font-family:'宋体';" lang="en-us" xml:lang="en-us"></span></span></p>
<p class="MsoNormal" style="margin:11.25pt 0cm;line-height:18pt;text-align:left;" align="left"><span style="font-family:'宋体';"><span style="font-size:medium;">这里有一些<span lang="en-us" xml:lang="en-us">RSS</span>样本文件：<span lang="en-us" xml:lang="en-us"> RSS 0.91, 0.92 </span>和 <span lang="en-us" xml:lang="en-us">2.0</span>。<span lang="en-us" xml:lang="en-us"></span></span></span></p>
<p class="MsoNormal" style="margin:11.25pt 0cm;line-height:18pt;text-align:left;" align="left"><span style="font-family:'宋体';"><span style="font-size:medium;">注意这些样本文件所指向的链接地址和服务器可能已经不再存在。在撰写<span lang="en-us" xml:lang="en-us">0.91</span>文档的时候，这个<span lang="en-us" xml:lang="en-us">0.91</span>的样本文件就已经创建了。维护一个样本文件的历史也许是一个不错的主意。<span lang="en-us" xml:lang="en-us"></span></span></span></p>
<p class="MsoNormal" style="margin:11.25pt 0cm 11.25pt 21pt;text-indent:-21pt;line-height:18pt;text-align:left;" align="left"><span style="font-size:medium;"><span style="font-family:'宋体';" lang="en-us" xml:lang="en-us"><span>三、</span></span><strong><span style="font-family:'宋体';">关于文档<span lang="en-us" xml:lang="en-us"><a href="http://www.sssdf.com/show.jsp?categoryid=2&amp;id=00012#aboutThisDocument" target="_blank"></a></span></span></strong><span style="font-family:'宋体';" lang="en-us" xml:lang="en-us"></span></span></p>
<p class="MsoNormal" style="margin:11.25pt 0cm;line-height:18pt;text-align:left;" align="left"><span style="font-family:'宋体';"><span style="font-size:medium;">本文档完成于<span lang="en-us" xml:lang="en-us">2002</span>年秋天，版本为<span lang="en-us" xml:lang="en-us"> 2.0.1</span>。<span lang="en-us" xml:lang="en-us"></span></span></span></p>
<p class="MsoNormal" style="margin:11.25pt 0cm;line-height:18pt;text-align:left;" align="left"><span style="font-family:'宋体';"><span style="font-size:medium;">它包含从 <span lang="en-us" xml:lang="en-us">RSS 0.91 </span>规范<span lang="en-us" xml:lang="en-us">(2000</span>年<span lang="en-us" xml:lang="en-us">)</span>开始的所有的修改和添加，以及包含在<span lang="en-us" xml:lang="en-us">RSS 0.92 </span>（<span lang="en-us" xml:lang="en-us">2000</span>年<span lang="en-us" xml:lang="en-us">12</span>月）和<span lang="en-us" xml:lang="en-us">RSS 0.94</span>（<span lang="en-us" xml:lang="en-us">2002</span>年<span lang="en-us" xml:lang="en-us">8</span>月）中的新的特性。<span lang="en-us" xml:lang="en-us"></span></span></span></p>
<p class="MsoNormal" style="margin:11.25pt 0cm;line-height:18pt;text-align:left;" align="left"><span style="font-family:'宋体';"><span style="font-size:medium;">本文档中首先介绍必须的和可选的频道元素；接着介绍了<span lang="en-us" xml:lang="en-us">&lt;item&gt;</span>的子元素。最后回答了一些经常碰到的问题，并提供了未来的发展路线和<span lang="en-us" xml:lang="en-us">RSS</span>扩展的指导方针。<span lang="en-us" xml:lang="en-us"></span></span></span></p>
<p class="MsoNormal" style="margin:11.25pt 0cm 11.25pt 21pt;text-indent:-21pt;line-height:18pt;text-align:left;" align="left"><span style="font-size:medium;"><span style="font-family:'宋体';" lang="en-us" xml:lang="en-us"><span>四、</span></span><strong><span style="font-family:'宋体';">必需的频道元素<span lang="en-us" xml:lang="en-us"><a href="http://www.sssdf.com/show.jsp?categoryid=2&amp;id=00012#requiredChannelElements" target="_blank"></a></span></span></strong><span style="font-family:'宋体';" lang="en-us" xml:lang="en-us"></span></span></p>
<p class="MsoNormal" style="margin:11.25pt 0cm;line-height:18pt;text-align:left;" align="left"><span style="font-family:'宋体';"><span style="font-size:medium;">下面是一个必须包含的频道<span lang="en-us" xml:lang="en-us">(channel)</span>元素的列表，每一个都有一个简单的描述、一个例子、应该出现的位置和更详细描述的链接地址。<span lang="en-us" xml:lang="en-us"></span></span></span></p>
<p class="MsoNormal" style="margin:11.25pt 0cm;line-height:18pt;text-align:left;" align="left"><span style="font-family:'宋体';" lang="en-us" xml:lang="en-us"><span style="font-size:medium;">01.●</span></span><span style="font-family:'宋体';"><span style="font-size:medium;">　</span><span style="font-size:medium;"><span lang="en-us" xml:lang="en-us">title  <br /></span>名称：</span><span style="font-size:medium;"><span lang="en-us" xml:lang="en-us">title <br /></span>描述：频道的名称。它表明别人如何访问你的服务。如果你有一个与你的<span lang="en-us" xml:lang="en-us">RSS</span>文件内容一致的<span lang="en-us" xml:lang="en-us">HTML</span>网站，你的<span lang="en-us" xml:lang="en-us">title</span>元素值应该与你的网站的标题相同。</span><span style="font-size:medium;"><span lang="en-us" xml:lang="en-us"> <br /></span>例子：<span lang="en-us" xml:lang="en-us">GoUpstate.com </span>的新闻大字标题。<span lang="en-us" xml:lang="en-us"></span></span></span></p>
<p class="MsoNormal" style="margin:11.25pt 0cm;line-height:18pt;text-align:left;" align="left"><span style="font-family:'宋体';" lang="en-us" xml:lang="en-us"><span style="font-size:medium;">02.●</span></span><span style="font-family:'宋体';"><span style="font-size:medium;">　</span><span style="font-size:medium;"><span lang="en-us" xml:lang="en-us">link  <br /></span>名称：</span><span style="font-size:medium;"><span lang="en-us" xml:lang="en-us">link <br /></span>描述：对应频道的网站的<span lang="en-us" xml:lang="en-us">URL</span>链接地址。</span><span style="font-size:medium;"><span lang="en-us" xml:lang="en-us"> <br /></span>例子：<span lang="en-us" xml:lang="en-us">http://www.goupstate.com/ </span>。<span lang="en-us" xml:lang="en-us"></span></span></span></p>
<p class="MsoNormal" style="margin:11.25pt 0cm;line-height:18pt;text-align:left;" align="left"><span style="font-family:'宋体';" lang="en-us" xml:lang="en-us"><span style="font-size:medium;">03.●</span></span><span style="font-family:'宋体';"><span style="font-size:medium;">　</span><span style="font-size:medium;"><span lang="en-us" xml:lang="en-us">description  <br /></span>名称：</span><span style="font-size:medium;"><span lang="en-us" xml:lang="en-us">description <br /></span>描述：关于频道的描述。</span><span style="font-size:medium;"><span lang="en-us" xml:lang="en-us"> <br /></span>例子：<span lang="en-us" xml:lang="en-us">The latest news from GoUpstate.com, a Spartanburg Herald-Journal Web site</span>。<span lang="en-us" xml:lang="en-us"></span></span></span></p>
<p class="MsoNormal" style="margin:11.25pt 0cm 11.25pt 21pt;text-indent:-21pt;line-height:18pt;text-align:left;" align="left"><span style="font-size:medium;"><span style="font-family:'宋体';" lang="en-us" xml:lang="en-us"><span>五、</span></span><strong><span style="font-family:'宋体';">可选的频道元素</span></strong><span style="font-family:'宋体';" lang="en-us" xml:lang="en-us"><a href="http://www.sssdf.com/show.jsp?categoryid=2&amp;id=00012#optionalChannelElements" target="_blank"></a></span></span></p>
<p class="MsoNormal" style="margin:0cm 0cm 0pt;line-height:18pt;text-align:left;" align="left"><span style="font-family:'宋体';"><span style="font-size:medium;">下面是一个可选的频道<span lang="en-us" xml:lang="en-us">(channel)</span>元素的列表。<span lang="en-us" xml:lang="en-us"></span></span></span></p>
<p class="MsoNormal" style="margin:11.25pt 0cm;line-height:18pt;text-align:left;" align="left"><span style="font-family:'宋体';" lang="en-us" xml:lang="en-us"><span style="font-size:medium;">01.●</span></span><span style="font-family:'宋体';"><span style="font-size:medium;">　</span><span style="font-size:medium;"><span lang="en-us" xml:lang="en-us">language<br /></span>名称：</span><span style="font-size:medium;"><span lang="en-us" xml:lang="en-us">language<br /></span>描述：频道使用的语言。比如，在一个网站上，允许聚合所有的意大利语站点到相应的分组。对于这个元素，可使用的值，参阅<span lang="en-us" xml:lang="en-us"> Netscape</span>提供的清单。或者可以参阅<span lang="en-us" xml:lang="en-us">W3C</span>定义的 清单。</span><span style="font-size:medium;"><span lang="en-us" xml:lang="en-us"> <br /></span>例子：<span lang="en-us" xml:lang="en-us">en-us</span>。<span lang="en-us" xml:lang="en-us"></span></span></span></p>
<p class="MsoNormal" style="margin:11.25pt 0cm;line-height:18pt;text-align:left;" align="left"><span style="font-family:'宋体';" lang="en-us" xml:lang="en-us"><span style="font-size:medium;">02.●</span></span><span style="font-family:'宋体';"><span style="font-size:medium;">　</span><span style="font-size:medium;"><span lang="en-us" xml:lang="en-us">copyright<br /></span>名称：</span><span style="font-size:medium;"><span lang="en-us" xml:lang="en-us">copyright<br /></span>描述：频道内容的版权声明。</span><span style="font-size:medium;"><span lang="en-us" xml:lang="en-us"> <br /></span>例子：<span lang="en-us" xml:lang="en-us">Copyright 2002, Spartanburg Herald-Journal </span></span></span></p>
<p class="MsoNormal" style="margin:11.25pt 0cm;line-height:18pt;text-align:left;" align="left"><span style="font-family:'宋体';" lang="en-us" xml:lang="en-us"><span style="font-size:medium;">03.●</span></span><span style="font-family:'宋体';"><span style="font-size:medium;">　</span><span style="font-size:medium;"><span lang="en-us" xml:lang="en-us">managingEditor<br /></span>名称：</span><span style="font-size:medium;"><span lang="en-us" xml:lang="en-us">managingEditor<br /></span>描述：频道内容责任编辑的电子邮件地址。</span><span style="font-size:medium;"><span lang="en-us" xml:lang="en-us"> <br /></span>例子：<span lang="en-us" xml:lang="en-us">geo@herald.com (George Matesky) </span></span></span></p>
<p class="MsoNormal" style="margin:11.25pt 0cm;line-height:18pt;text-align:left;" align="left"><span style="font-family:'宋体';" lang="en-us" xml:lang="en-us"><span style="font-size:medium;">04.●</span></span><span style="font-family:'宋体';"><span style="font-size:medium;">　</span><span style="font-size:medium;"><span lang="en-us" xml:lang="en-us">webMaster<br /></span>名称：</span><span style="font-size:medium;"><span lang="en-us" xml:lang="en-us">webMaster<br /></span>描述：频道技术支持人员的电子邮件地址。</span><span style="font-size:medium;"><span lang="en-us" xml:lang="en-us"> <br /></span>例子：<span lang="en-us" xml:lang="en-us">betty@herald.com (Betty Guernsey) </span></span></span></p>
<p class="MsoNormal" style="margin:11.25pt 0cm;line-height:18pt;text-align:left;" align="left"><span style="font-family:'宋体';" lang="en-us" xml:lang="en-us"><span style="font-size:medium;">05.●</span></span><span style="font-family:'宋体';"><span style="font-size:medium;">　</span><span style="font-size:medium;"><span lang="en-us" xml:lang="en-us">pubDate<br /></span>名称：</span><span style="font-size:medium;"><span lang="en-us" xml:lang="en-us">pubDate<br /></span>描述：频道内容发布的日期。所有的日期和时间都必须遵循 <span lang="en-us" xml:lang="en-us">RFC 822</span>规范<span lang="en-us" xml:lang="en-us">, </span>但年份可以用２个或４个字母表示<span lang="en-us" xml:lang="en-us">(</span>首选４个字母<span lang="en-us" xml:lang="en-us">)</span>。</span><span style="font-size:medium;"><span lang="en-us" xml:lang="en-us"> <br /></span>例子：<span lang="en-us" xml:lang="en-us">Sat, 07 Sep 2002 00:00:01 GMT </span></span></span></p>
<p class="MsoNormal" style="margin:11.25pt 0cm;line-height:18pt;text-align:left;" align="left"><span style="font-family:'宋体';" lang="en-us" xml:lang="en-us"><span style="font-size:medium;">06.●</span></span><span style="font-family:'宋体';"><span style="font-size:medium;">　</span><span style="font-size:medium;"><span lang="en-us" xml:lang="en-us">lastBuildDate<br /></span>名称：</span><span style="font-size:medium;"><span lang="en-us" xml:lang="en-us">lastBuildDate<br /></span>描述：频道内容的最后修改时间。</span><span style="font-size:medium;"><span lang="en-us" xml:lang="en-us"> <br /></span>例子：<span lang="en-us" xml:lang="en-us">Sat, 07 Sep 2002 09:42:31 GMT </span></span></span></p>
<p class="MsoNormal" style="margin:11.25pt 0cm;line-height:18pt;text-align:left;" align="left"><span style="font-family:'宋体';" lang="en-us" xml:lang="en-us"><span style="font-size:medium;">07.●</span></span><span style="font-family:'宋体';"><span style="font-size:medium;">　</span><span style="font-size:medium;"><span lang="en-us" xml:lang="en-us">category<br /></span>名称：</span><span style="font-size:medium;"><span lang="en-us" xml:lang="en-us">category <br /></span>描述：指定频道所属的一个或多个分类。遵循与<span lang="en-us" xml:lang="en-us">item</span>级<span lang="en-us" xml:lang="en-us">category</span>元素相同的规则。</span><span lang="en-us" xml:lang="en-us"><br /></span><span style="font-size:medium;">例子：<span lang="en-us" xml:lang="en-us">&lt;category&gt;Newspapers&lt;/category&gt; </span></span></span></p>
<p class="MsoNormal" style="margin:11.25pt 0cm;line-height:18pt;text-align:left;" align="left"><span style="font-family:'宋体';" lang="en-us" xml:lang="en-us"><span style="font-size:medium;">08.●</span></span><span style="font-family:'宋体';"><span style="font-size:medium;">　</span><span style="font-size:medium;"><span lang="en-us" xml:lang="en-us">generator<br /></span>名称：</span><span style="font-size:medium;"><span lang="en-us" xml:lang="en-us">generator <br /></span>描述：表明生成频道的程序名称的字符串。</span><span style="font-size:medium;"><span lang="en-us" xml:lang="en-us"> <br /></span>例子：<span lang="en-us" xml:lang="en-us">MightyInHouse Content System v2.3 </span></span></span></p>
<p class="MsoNormal" style="margin:11.25pt 0cm;line-height:18pt;text-align:left;" align="left"><span style="font-family:'宋体';" lang="en-us" xml:lang="en-us"><span style="font-size:medium;">09.●</span></span><span style="font-family:'宋体';"><span style="font-size:medium;">　</span><span style="font-size:medium;"><span lang="en-us" xml:lang="en-us">docs<br /></span>名称：</span><span style="font-size:medium;"><span lang="en-us" xml:lang="en-us">docs<br /></span>描述：指向该<span lang="en-us" xml:lang="en-us">RSS</span>文件所用格式说明文档的<span lang="en-us" xml:lang="en-us">URL</span>链接地址。</span><span style="font-size:medium;"><span lang="en-us" xml:lang="en-us"> <br /></span>例子：<span lang="en-us" xml:lang="en-us">http://blogs.law.harvard.edu/tech/rss</span>。<span lang="en-us" xml:lang="en-us"></span></span></span></p>
<p class="MsoNormal" style="margin:11.25pt 0cm;line-height:18pt;text-align:left;" align="left"><span style="font-family:'宋体';" lang="en-us" xml:lang="en-us"><span style="font-size:medium;">10.●</span></span><span style="font-family:'宋体';"><span style="font-size:medium;">　</span><span style="font-size:medium;"><span lang="en-us" xml:lang="en-us">cloud<br /></span>名称：</span><span style="font-size:medium;"><span lang="en-us" xml:lang="en-us">cloud<br /></span>描述：允许通过注册一个<span lang="en-us" xml:lang="en-us">cloud</span>来处理获得频道的更新通知，并为<span lang="en-us" xml:lang="en-us">rss</span>种子实现一个轻量级的发布订阅协议。</span><span style="font-size:medium;"><span lang="en-us" xml:lang="en-us"> <br /></span>例子：<span lang="en-us" xml:lang="en-us">&lt;cloud domain="rpc.sys.com" port="80" path="/RPC2" registerProcedure="pingMe" protocol="soap"/&gt; </span></span></span></p>
<p class="MsoNormal" style="margin:11.25pt 0cm;line-height:18pt;text-align:left;" align="left"><span style="font-family:'宋体';" lang="en-us" xml:lang="en-us"><span style="font-size:medium;">11.●</span></span><span style="font-family:'宋体';"><span style="font-size:medium;">　</span><span style="font-size:medium;"><span lang="en-us" xml:lang="en-us">ttl<br /></span>名称：</span><span style="font-size:medium;"><span lang="en-us" xml:lang="en-us">ttl <br /></span>描述：<span lang="en-us" xml:lang="en-us">ttl</span>是<span lang="en-us" xml:lang="en-us">Time to live</span>的缩写，表示生存时间。它表示频道从源更新之前可以缓存的时间。</span><span style="font-size:medium;"><span lang="en-us" xml:lang="en-us"> <br /></span>例子：<span lang="en-us" xml:lang="en-us">&lt;ttl&gt;60&lt;/ttl&gt;</span>。<span lang="en-us" xml:lang="en-us"></span></span></span></p>
<p class="MsoNormal" style="margin:11.25pt 0cm;line-height:18pt;text-align:left;" align="left"><span style="font-family:'宋体';" lang="en-us" xml:lang="en-us"><span style="font-size:medium;">12.●</span></span><span style="font-family:'宋体';"><span style="font-size:medium;">　</span><span style="font-size:medium;"><span lang="en-us" xml:lang="en-us">image<br /></span>名称：</span><span style="font-size:medium;"><span lang="en-us" xml:lang="en-us">image<br /></span>描述：指定一个可以在频道中显示的<span lang="en-us" xml:lang="en-us">GIF</span>、<span lang="en-us" xml:lang="en-us">JPEG</span>或者<span lang="en-us" xml:lang="en-us"> PNG </span>图像。</span><span style="font-size:medium;"><span lang="en-us" xml:lang="en-us"> <br /></span>例子：。<span lang="en-us" xml:lang="en-us"></span></span></span></p>
<p class="MsoNormal" style="margin:11.25pt 0cm;line-height:18pt;text-align:left;" align="left"><span style="font-family:'宋体';" lang="en-us" xml:lang="en-us"><span style="font-size:medium;">13.●</span></span><span style="font-family:'宋体';"><span style="font-size:medium;">　</span><span style="font-size:medium;"><span lang="en-us" xml:lang="en-us">rating<br /></span>名称：</span><span style="font-size:medium;"><span lang="en-us" xml:lang="en-us">rating<br /></span>描述：频道的 <span lang="en-us" xml:lang="en-us">PICS </span>内容分级信息。</span><span style="font-size:medium;"><span lang="en-us" xml:lang="en-us"> <br /></span>例子： 。<span lang="en-us" xml:lang="en-us"></span></span></span></p>
<p class="MsoNormal" style="margin:11.25pt 0cm;line-height:18pt;text-align:left;" align="left"><span style="font-family:'宋体';" lang="en-us" xml:lang="en-us"><span style="font-size:medium;">14.●</span></span><span style="font-family:'宋体';"><span style="font-size:medium;">　</span><span style="font-size:medium;"><span lang="en-us" xml:lang="en-us">textInput<br /></span>名称：</span><span style="font-size:medium;"><span lang="en-us" xml:lang="en-us">textInput<br /></span>描述：指定一个可以在频道中显示的文本输入框。</span><span lang="en-us" xml:lang="en-us"><br /></span><span style="font-size:medium;">例子：。<span lang="en-us" xml:lang="en-us"></span></span></span></p>
<p class="MsoNormal" style="margin:11.25pt 0cm;line-height:18pt;text-align:left;" align="left"><span style="font-family:'宋体';" lang="en-us" xml:lang="en-us"><span style="font-size:medium;">15.●</span></span><span style="font-family:'宋体';"><span style="font-size:medium;">　</span><span style="font-size:medium;"><span lang="en-us" xml:lang="en-us">skipHours<br /></span>名称：</span><span style="font-size:medium;"><span lang="en-us" xml:lang="en-us">skipHours<br /></span>描述：提示聚合器，可以跳过那些小时的时间段。</span><span lang="en-us" xml:lang="en-us"><br /></span><span style="font-size:medium;">例子：。<span lang="en-us" xml:lang="en-us"></span></span></span></p>
<p class="MsoNormal" style="margin:11.25pt 0cm;line-height:18pt;text-align:left;" align="left"><span style="font-family:'宋体';" lang="en-us" xml:lang="en-us"><span style="font-size:medium;">16.●</span></span><span style="font-family:'宋体';"><span style="font-size:medium;">　</span><span style="font-size:medium;"><span lang="en-us" xml:lang="en-us">skipDays<br /></span>名称：</span><span style="font-size:medium;"><span lang="en-us" xml:lang="en-us">skipDays<br /></span>描述：提示聚合器，可以跳过那些天的时间段。</span><span lang="en-us" xml:lang="en-us"><br /></span><span style="font-size:medium;">例子：。<span lang="en-us" xml:lang="en-us"></span></span></span></p>
<p class="MsoNormal" style="margin:11.25pt 0cm;line-height:18pt;text-align:left;" align="left"><span style="font-size:medium;"><strong><span style="font-family:'宋体';" lang="en-us" xml:lang="en-us">&lt;channel&gt;</span></strong><strong><span style="font-family:'宋体';">的子元素<span lang="en-us" xml:lang="en-us">&lt;image&gt; <a href="http://www.sssdf.com/show.jsp?categoryid=2&amp;id=00012#ltimagegtSubelementOfLtchannelgt" target="_blank"></a></span></span></strong><span style="font-family:'宋体';" lang="en-us" xml:lang="en-us"></span></span></p>
<p class="MsoNormal" style="margin:11.25pt 0cm;line-height:18pt;text-align:left;" align="left"><span style="font-family:'宋体';" lang="en-us" xml:lang="en-us"><span style="font-size:medium;">&lt;image&gt; </span></span><span style="font-family:'宋体';"><span style="font-size:medium;">是<span lang="en-us" xml:lang="en-us"> &lt;channel&gt;</span>的一个可选子元素<span lang="en-us" xml:lang="en-us">, </span>它本身包含了三个必须的和三个可选的子元素。</span><span lang="en-us" xml:lang="en-us"><br /><span style="font-size:medium;">&lt;url&gt;</span></span><span style="font-size:medium;">是一个<span lang="en-us" xml:lang="en-us">GIF</span>、<span lang="en-us" xml:lang="en-us">JPEG</span>或<span lang="en-us" xml:lang="en-us">PNG</span>图像文件的<span lang="en-us" xml:lang="en-us">URL</span>链接地址，该图像代表整个频道。</span><span lang="en-us" xml:lang="en-us"><br /><span style="font-size:medium;">&lt;title&gt;</span></span><span style="font-size:medium;">用于描述上面的图像，当频道在<span lang="en-us" xml:lang="en-us">HTML</span>中显示时，用于<span lang="en-us" xml:lang="en-us">HTML</span>语言中的<span lang="en-us" xml:lang="en-us">&lt;img&gt;</span>的<span lang="en-us" xml:lang="en-us">alt</span>属性。<span lang="en-us" xml:lang="en-us"></span></span></span></p>
<p class="MsoNormal" style="margin:11.25pt 0cm;line-height:18pt;text-align:left;" align="left"><span style="font-family:'宋体';" lang="en-us" xml:lang="en-us"><span style="font-size:medium;">&lt;link&gt;</span></span><span style="font-family:'宋体';"><span style="font-size:medium;">是要连接的站点的<span lang="en-us" xml:lang="en-us">url</span>，当显示频道时，图像的连接指向该站点。<span lang="en-us" xml:lang="en-us">(</span>在实际中，<span lang="en-us" xml:lang="en-us">&lt;title&gt;</span>和<span lang="en-us" xml:lang="en-us">&lt;link&gt;</span>应该与频道的<span lang="en-us" xml:lang="en-us">&lt;title&gt;</span>和<span lang="en-us" xml:lang="en-us">&lt;link&gt;</span>有相同的值<span lang="en-us" xml:lang="en-us">)</span>。</span><span lang="en-us" xml:lang="en-us"><br /></span><span style="font-size:medium;">可选的元素包括<span lang="en-us" xml:lang="en-us">&lt;width&gt;</span>和<span lang="en-us" xml:lang="en-us">&lt;height&gt;</span>，它们是数字类型，指定图像的宽度和高度，单位为像素。</span><span lang="en-us" xml:lang="en-us"><br /><span style="font-size:medium;">&lt;description&gt;</span></span><span style="font-size:medium;">就是<span lang="en-us" xml:lang="en-us">link</span>的<span lang="en-us" xml:lang="en-us">TITLE</span>属性中文本，它将在调用网页时显示出来。 </span><span lang="en-us" xml:lang="en-us"><br /></span><span style="font-size:medium;">图像宽度的最大值为<span lang="en-us" xml:lang="en-us">144</span>，默认值为<span lang="en-us" xml:lang="en-us">88 </span>。</span><span lang="en-us" xml:lang="en-us"><br /></span><span style="font-size:medium;">图像高度的最大值为<span lang="en-us" xml:lang="en-us">400</span>，默认值为<span lang="en-us" xml:lang="en-us">31 </span>。<span lang="en-us" xml:lang="en-us"></span></span></span></p>
<p class="MsoNormal" style="margin:11.25pt 0cm;line-height:18pt;text-align:left;" align="left"><span style="font-size:medium;"><strong><span style="font-family:'宋体';" lang="en-us" xml:lang="en-us">&lt;channel&gt;</span></strong><strong><span style="font-family:'宋体';">的子元素<span lang="en-us" xml:lang="en-us">&lt;cloud&gt;<a href="http://www.sssdf.com/show.jsp?categoryid=2&amp;id=00012#ltcloudgtSubelementOfLtchannelgt" target="_blank"></a></span></span></strong><span style="font-family:'宋体';" lang="en-us" xml:lang="en-us"></span></span></p>
<p class="MsoNormal" style="margin:11.25pt 0cm;line-height:18pt;text-align:left;" align="left"><span style="font-size:medium;"><span style="font-family:'宋体';" lang="en-us" xml:lang="en-us">&lt;cloud&gt; </span><span style="font-family:'宋体';">是<span lang="en-us" xml:lang="en-us"> &lt;channel&gt;</span>的一个可选子元素。<span lang="en-us" xml:lang="en-us"></span></span></span></p>
<p class="MsoNormal" style="margin:11.25pt 0cm;line-height:18pt;text-align:left;" align="left"><span style="font-family:'宋体';"><span style="font-size:medium;">它指定一个可以支持<span lang="en-us" xml:lang="en-us">rssCloud</span>接口的<span lang="en-us" xml:lang="en-us">web</span>服务，<span lang="en-us" xml:lang="en-us">rssCloud</span>接口可以在<span lang="en-us" xml:lang="en-us">HTTP-POST</span>、<span lang="en-us" xml:lang="en-us">XML-RPC</span>或<span lang="en-us" xml:lang="en-us">SOAP1.1</span>中实现。<span lang="en-us" xml:lang="en-us"></span></span></span></p>
<p class="MsoNormal" style="margin:11.25pt 0cm;line-height:18pt;text-align:left;" align="left"><span style="font-family:'宋体';"><span style="font-size:medium;">它的目的是允许通过注册一个<span lang="en-us" xml:lang="en-us">cloud</span>来处理获得频道的更新通知，从而为<span lang="en-us" xml:lang="en-us">RSS feeds</span>实现一个轻量级的发布订阅协议<span lang="en-us" xml:lang="en-us">.</span></span></span></p>
<p class="MsoNormal" style="margin:11.25pt 0cm;line-height:18pt;text-align:left;" align="left"><span style="font-size:medium;"><span style="font-family:'宋体';" lang="en-us" xml:lang="en-us">&lt;cloud domain="rpc.sys.com" port="80" path="/RPC2" registerProcedure="myCloud.rssPleaseNotify" protocol="xml-rpc" /&gt;<br /></span><span style="font-family:'宋体';">在这个例子中，为了请求频道通知，你需要发送一个<span lang="en-us" xml:lang="en-us">XML-RPC</span>消息到<span lang="en-us" xml:lang="en-us">rpc.sys.com</span>的<span lang="en-us" xml:lang="en-us">80</span>端口，路径为<span lang="en-us" xml:lang="en-us">/RPC2</span>。调用的程序为为<span lang="en-us" xml:lang="en-us">myCloud.rssPleaseNotify</span>。<span lang="en-us" xml:lang="en-us"></span></span></span></p>
<p class="MsoNormal" style="margin:11.25pt 0cm;line-height:18pt;text-align:left;" align="left"><span style="font-family:'宋体';"><span style="font-size:medium;">这个元素的详细说明和<span lang="en-us" xml:lang="en-us"> rssCloud </span>接口说明请参阅<span lang="en-us" xml:lang="en-us">http://blogs.law.harvard.edu/tech/soapMeetsRss#rsscloudInterface</span>。<span lang="en-us" xml:lang="en-us"></span></span></span></p>
<p class="MsoNormal" style="margin:11.25pt 0cm;line-height:18pt;text-align:left;" align="left"><span style="font-size:medium;"><strong><span style="font-family:'宋体';" lang="en-us" xml:lang="en-us">&lt;channel&gt;</span></strong><strong><span style="font-family:'宋体';">子元素<span lang="en-us" xml:lang="en-us">&lt;ttl&gt;<a href="http://www.sssdf.com/show.jsp?categoryid=2&amp;id=00012#ltttlgtSubelementOfLtchannelgt" target="_blank"></a></span></span></strong><span style="font-family:'宋体';" lang="en-us" xml:lang="en-us"></span></span></p>
<p class="MsoNormal" style="margin:11.25pt 0cm;line-height:18pt;text-align:left;" align="left"><span style="font-size:medium;"><span style="font-family:'宋体';" lang="en-us" xml:lang="en-us">&lt;ttl&gt;&lt;channel&gt;</span><span style="font-family:'宋体';">的一个可选子元素。<span lang="en-us" xml:lang="en-us"></span></span></span></p>
<p class="MsoNormal" style="margin:11.25pt 0cm;line-height:18pt;text-align:left;" align="left"><span style="font-family:'宋体';" lang="en-us" xml:lang="en-us"><span style="font-size:medium;">ttl</span></span><span style="font-family:'宋体';"><span style="font-size:medium;">是<span lang="en-us" xml:lang="en-us">Time to live</span>的缩写，表示生存时间。它表示频道从源重新更新之前可以缓存的时间。这使得<span lang="en-us" xml:lang="en-us">rss</span>源可以被一个支持文件共享的网络所管理，例如<span lang="en-us" xml:lang="en-us">Gnutella</span>。</span><span lang="en-us" xml:lang="en-us"><br /></span><span style="font-size:medium;">例子<span lang="en-us" xml:lang="en-us">: &lt;ttl&gt;60&lt;/ttl&gt;</span></span></span></p>
<p class="MsoNormal" style="margin:11.25pt 0cm;line-height:18pt;text-align:left;" align="left"><span style="font-size:medium;"><strong><span style="font-family:'宋体';" lang="en-us" xml:lang="en-us">&lt;channel&gt;</span></strong><strong><span style="font-family:'宋体';">的子元素<span lang="en-us" xml:lang="en-us">&lt;textInput&gt;<a href="http://www.sssdf.com/show.jsp?categoryid=2&amp;id=00012#lttextinputgtSubelementOfLtchannelgt" target="_blank"></a></span></span></strong><span style="font-family:'宋体';" lang="en-us" xml:lang="en-us"></span></span></p>
<p class="MsoNormal" style="margin:11.25pt 0cm;line-height:18pt;text-align:left;" align="left"><span style="font-family:'宋体';"><span style="font-size:medium;">频道可以选择包含一个<span lang="en-us" xml:lang="en-us">&lt;textInput&gt;</span>子元素，它本身包含了四个必须的子元素。</span><span lang="en-us" xml:lang="en-us"><br /><span style="font-size:medium;">&lt;title&gt;--</span></span><span style="font-size:medium;">文本输入区域提交按钮的标签。</span><span lang="en-us" xml:lang="en-us"><br /><span style="font-size:medium;">&lt;description&gt;--</span></span><span style="font-size:medium;">文本输入区域的描述。</span><span lang="en-us" xml:lang="en-us"><br /><span style="font-size:medium;">&lt;name&gt;--</span></span><span style="font-size:medium;">文本输入区域中文本对象的名称。</span><span lang="en-us" xml:lang="en-us"><br /><span style="font-size:medium;">&lt;link&gt;--</span></span><span style="font-size:medium;">处理文本输入请求的<span lang="en-us" xml:lang="en-us">CGI</span>脚本的<span lang="en-us" xml:lang="en-us">URL</span>链接地址。</span><span lang="en-us" xml:lang="en-us"><br /></span><span style="font-size:medium;">使用<span lang="en-us" xml:lang="en-us">&lt;textInput&gt;</span>元素的目的看起来有些神秘。你可以用它提供一个搜索引擎输入框，或让读者提供反馈信息。许多聚合器忽略该元素。<span lang="en-us" xml:lang="en-us"></span></span></span></p>
<p class="MsoNormal" style="margin:11.25pt 0cm 11.25pt 21pt;text-indent:-21pt;line-height:18pt;text-align:left;" align="left"><span style="font-size:medium;"><span style="font-family:'宋体';" lang="en-us" xml:lang="en-us"><span>六、</span></span><strong><span style="font-family:'宋体';" lang="en-us" xml:lang="en-us">&lt;item&gt;</span></strong><strong><span style="font-family:'宋体';">的元素<span lang="en-us" xml:lang="en-us"><a href="http://www.sssdf.com/show.jsp?categoryid=2&amp;id=00012#hrelementsOfLtitemgt" target="_blank"></a></span></span></strong><span style="font-family:'宋体';" lang="en-us" xml:lang="en-us"></span></span></p>
<p class="MsoNormal" style="margin:11.25pt 0cm;line-height:18pt;text-align:left;" align="left"><span style="font-family:'宋体';"><span style="font-size:medium;">一个频道可以包含许多<span lang="en-us" xml:lang="en-us">&lt;item&gt;</span>元素。一个项目可以代表一个<span lang="en-us" xml:lang="en-us">"</span>故事<span lang="en-us" xml:lang="en-us">" ——</span>比如说一份报纸或杂志上的故事；如果是这样的话，那么项目的描述则是故事的摘要，项目的链接则指向整个故事的链接位置。一个项目也可以本身是完整的，如果是这样的话，项目的描述就包含了文本<span lang="en-us" xml:lang="en-us">(</span>整体以<span lang="en-us" xml:lang="en-us">HTML</span>格式编码是可以的<span lang="en-us" xml:lang="en-us">)</span>，而链接和标题可以省略。项目的所有元素都是可选的，但是至少要包含一个标题<span lang="en-us" xml:lang="en-us">(title)</span>或描述<span lang="en-us" xml:lang="en-us">(description)</span>。<span lang="en-us" xml:lang="en-us"></span></span></span></p>
<p class="MsoNormal" style="margin:11.25pt 0cm;line-height:18pt;text-align:left;" align="left"><span style="font-family:'宋体';" lang="en-us" xml:lang="en-us"><span style="font-size:medium;">01.●</span></span><span style="font-family:'宋体';"><span style="font-size:medium;">　</span><span style="font-size:medium;"><span lang="en-us" xml:lang="en-us">title<br /></span>名称：</span><span style="font-size:medium;"><span lang="en-us" xml:lang="en-us">title<br /></span>描述：<span lang="en-us" xml:lang="en-us">item</span>的标题。</span><span style="font-size:medium;"><span lang="en-us" xml:lang="en-us"> <br /></span>例子：<span lang="en-us" xml:lang="en-us">Venice</span><span lang="en-us" xml:lang="en-us"> Film Festival Tries to Quit Sinking </span></span></span></p>
<p class="MsoNormal" style="margin:11.25pt 0cm;line-height:18pt;text-align:left;" align="left"><span style="font-family:'宋体';" lang="en-us" xml:lang="en-us"><span style="font-size:medium;">02.●</span></span><span style="font-family:'宋体';"><span style="font-size:medium;">　</span><span style="font-size:medium;"><span lang="en-us" xml:lang="en-us">link<br /></span>名称：</span><span style="font-size:medium;"><span lang="en-us" xml:lang="en-us">link<br /></span>描述：<span lang="en-us" xml:lang="en-us">item</span>的<span lang="en-us" xml:lang="en-us">URL</span>链接地址。</span><span style="font-size:medium;"><span lang="en-us" xml:lang="en-us"> <br /></span>例子：<span lang="en-us" xml:lang="en-us">http://nytimes.com/2004/12/07FEST.html</span></span></span></p>
<p class="MsoNormal" style="margin:11.25pt 0cm;line-height:18pt;text-align:left;" align="left"><span style="font-family:'宋体';" lang="en-us" xml:lang="en-us"><span style="font-size:medium;">03.●</span></span><span style="font-family:'宋体';"><span style="font-size:medium;">　</span><span style="font-size:medium;"><span lang="en-us" xml:lang="en-us">description     <br /></span>名称：</span><span style="font-size:medium;"><span lang="en-us" xml:lang="en-us">description     <br /></span>描述：<span lang="en-us" xml:lang="en-us">item</span>的摘要。</span><span style="font-size:medium;"><span lang="en-us" xml:lang="en-us"> <br /></span>例子：<span lang="en-us" xml:lang="en-us">Some of the most heated chatter at the Venice Film Festival this week was about the way that the arrival of the stars at the Palazzo del Cinema was being staged. </span></span></span></p>
<p class="MsoNormal" style="margin:11.25pt 0cm;line-height:18pt;text-align:left;" align="left"><span style="font-family:'宋体';" lang="en-us" xml:lang="en-us"><span style="font-size:medium;">04.●</span></span><span style="font-family:'宋体';"><span style="font-size:medium;">　</span><span style="font-size:medium;"><span lang="en-us" xml:lang="en-us">author<br /></span>名称：</span><span style="font-size:medium;"><span lang="en-us" xml:lang="en-us">author<br /></span>描述：<span lang="en-us" xml:lang="en-us">item</span>作者的电子邮件地址。</span><span lang="en-us" xml:lang="en-us"><br /></span><span style="font-size:medium;">例子：。<span lang="en-us" xml:lang="en-us"></span></span></span></p>
<p class="MsoNormal" style="margin:11.25pt 0cm;line-height:18pt;text-align:left;" align="left"><span style="font-family:'宋体';" lang="en-us" xml:lang="en-us"><span style="font-size:medium;">05.●</span></span><span style="font-family:'宋体';"><span style="font-size:medium;">　</span><span style="font-size:medium;"><span lang="en-us" xml:lang="en-us">category<br /></span>名称：</span><span style="font-size:medium;"><span lang="en-us" xml:lang="en-us">category<br /></span>描述：包含<span lang="en-us" xml:lang="en-us">item</span>在一个或多个分类中。</span><span lang="en-us" xml:lang="en-us"><br /></span><span style="font-size:medium;">例子：。<span lang="en-us" xml:lang="en-us"></span></span></span></p>
<p class="MsoNormal" style="margin:11.25pt 0cm;line-height:18pt;text-align:left;" align="left"><span style="font-family:'宋体';" lang="en-us" xml:lang="en-us"><span style="font-size:medium;">06.●</span></span><span style="font-family:'宋体';"><span style="font-size:medium;">　</span><span style="font-size:medium;"><span lang="en-us" xml:lang="en-us">comments<br /></span>名称：</span><span style="font-size:medium;"><span lang="en-us" xml:lang="en-us">comments<br /></span>描述：与<span lang="en-us" xml:lang="en-us">item</span>相关的评论的<span lang="en-us" xml:lang="en-us">URL</span>链接地址。</span><span lang="en-us" xml:lang="en-us"><br /></span><span style="font-size:medium;">例子：。<span lang="en-us" xml:lang="en-us"></span></span></span></p>
<p class="MsoNormal" style="margin:11.25pt 0cm;line-height:18pt;text-align:left;" align="left"><span style="font-family:'宋体';" lang="en-us" xml:lang="en-us"><span style="font-size:medium;">07.●</span></span><span style="font-family:'宋体';"><span style="font-size:medium;">　</span><span style="font-size:medium;"><span lang="en-us" xml:lang="en-us">enclosure<br /></span>名称：</span><span style="font-size:medium;"><span lang="en-us" xml:lang="en-us">enclosure<br /></span>描述：<span lang="en-us" xml:lang="en-us">item</span>附加的媒体对象。</span><span lang="en-us" xml:lang="en-us"><br /></span><span style="font-size:medium;">例子：。<span lang="en-us" xml:lang="en-us"></span></span></span></p>
<p class="MsoNormal" style="margin:11.25pt 0cm;line-height:18pt;text-align:left;" align="left"><span style="font-family:'宋体';" lang="en-us" xml:lang="en-us"><span style="font-size:medium;">08.●</span></span><span style="font-family:'宋体';"><span style="font-size:medium;">　</span><span style="font-size:medium;"><span lang="en-us" xml:lang="en-us">guid<br /></span>名称：</span><span style="font-size:medium;"><span lang="en-us" xml:lang="en-us">guid<br /></span>描述：可以唯一确定<span lang="en-us" xml:lang="en-us">item</span>身份的字符串。</span><span lang="en-us" xml:lang="en-us"><br /></span><span style="font-size:medium;">例子：。<span lang="en-us" xml:lang="en-us"></span></span></span></p>
<p class="MsoNormal" style="margin:11.25pt 0cm;line-height:18pt;text-align:left;" align="left"><span style="font-family:'宋体';" lang="en-us" xml:lang="en-us"><span style="font-size:medium;">09.●</span></span><span style="font-family:'宋体';"><span style="font-size:medium;">　</span><span style="font-size:medium;"><span lang="en-us" xml:lang="en-us">pubDate<br /></span>名称：</span><span style="font-size:medium;"><span lang="en-us" xml:lang="en-us">pubDate<br /></span>描述：<span lang="en-us" xml:lang="en-us">item</span>发布的时间。</span><span lang="en-us" xml:lang="en-us"><br /></span><span style="font-size:medium;">例子：。<span lang="en-us" xml:lang="en-us"></span></span></span></p>
<p class="MsoNormal" style="margin:11.25pt 0cm;line-height:18pt;text-align:left;" align="left"><span style="font-family:'宋体';" lang="en-us" xml:lang="en-us"><span style="font-size:medium;">10.●</span></span><span style="font-family:'宋体';"><span style="font-size:medium;">　</span><span style="font-size:medium;"><span lang="en-us" xml:lang="en-us">source<br /></span>名称：</span><span style="font-size:medium;"><span lang="en-us" xml:lang="en-us">source<br /></span>描述：<span lang="en-us" xml:lang="en-us">rss</span>频道来源。</span><span lang="en-us" xml:lang="en-us"><br /></span><span style="font-size:medium;">例子：。<span lang="en-us" xml:lang="en-us"></span></span></span></p>
<p class="MsoNormal" style="margin:11.25pt 0cm;line-height:18pt;text-align:left;" align="left"><span style="font-size:medium;"><strong><span style="font-family:'宋体';" lang="en-us" xml:lang="en-us">&lt;item&gt;</span></strong><strong><span style="font-family:'宋体';">的子元素<span lang="en-us" xml:lang="en-us">&lt;source&gt;<a href="http://www.sssdf.com/show.jsp?categoryid=2&amp;id=00012#ltsourcegtSubelementOfLtitemgt" target="_blank"></a></span></span></strong><span style="font-family:'宋体';" lang="en-us" xml:lang="en-us"></span></span></p>
<p class="MsoNormal" style="margin:11.25pt 0cm;line-height:18pt;text-align:left;" align="left"><span style="font-size:medium;"><span style="font-family:'宋体';" lang="en-us" xml:lang="en-us">&lt;source&gt;</span><span style="font-family:'宋体';">是<span lang="en-us" xml:lang="en-us">&lt;item&gt;</span>的一个可选子元素。<span lang="en-us" xml:lang="en-us"></span></span></span></p>
<p class="MsoNormal" style="margin:11.25pt 0cm;line-height:18pt;text-align:left;" align="left"><span style="font-family:'宋体';"><span style="font-size:medium;">它的值是<span lang="en-us" xml:lang="en-us">item</span>所属<span lang="en-us" xml:lang="en-us">rss</span>频道的名称，从<span lang="en-us" xml:lang="en-us">title</span>衍生而来。它有一个必须包含的属性<span lang="en-us" xml:lang="en-us">url, </span>该属性链接到<span lang="en-us" xml:lang="en-us">XML</span>序列化源。<span lang="en-us" xml:lang="en-us"></span></span></span></p>
<p class="MsoNormal" style="margin:11.25pt 0cm;line-height:18pt;text-align:left;" align="left"><span style="font-size:medium;"><span style="font-family:'宋体';" lang="en-us" xml:lang="en-us">&lt;source url="http://www.tomalak.org/links2.xml"&gt;Tomalak's Realm&lt;/source&gt;<br /></span><span style="font-family:'宋体';">该元素的作用是提高链接的声望，从而进一步推广新闻项目的源头。它可以用在聚合器的<span lang="en-us" xml:lang="en-us">Post</span>命令中。当从聚合器中通过一个<span lang="en-us" xml:lang="en-us">webblog</span>编辑工具提交一个<span lang="en-us" xml:lang="en-us">item</span>时，<span lang="en-us" xml:lang="en-us">&lt;source&gt;</span>应该能够被自动生成。<span lang="en-us" xml:lang="en-us"></span></span></span></p>
<p class="MsoNormal" style="margin:11.25pt 0cm;line-height:18pt;text-align:left;" align="left"><span style="font-size:medium;"><strong><span style="font-family:'宋体';" lang="en-us" xml:lang="en-us">&lt;item&gt;</span></strong><strong><span style="font-family:'宋体';">的子元素<span lang="en-us" xml:lang="en-us">&lt;enclosure&gt;<a href="http://www.sssdf.com/show.jsp?categoryid=2&amp;id=00012#ltenclosuregtSubelementOfLtitemgt" target="_blank"></a></span></span></strong><span style="font-family:'宋体';" lang="en-us" xml:lang="en-us"></span></span></p>
<p class="MsoNormal" style="margin:11.25pt 0cm;line-height:18pt;text-align:left;" align="left"><span style="font-size:medium;"><span style="font-family:'宋体';" lang="en-us" xml:lang="en-us">&lt;enclosure&gt;</span><span style="font-family:'宋体';">是<span lang="en-us" xml:lang="en-us">&lt;item&gt;</span>的一个可选子元素。<span lang="en-us" xml:lang="en-us"></span></span></span></p>
<p class="MsoNormal" style="margin:11.25pt 0cm;line-height:18pt;text-align:left;" align="left"><span style="font-family:'宋体';"><span style="font-size:medium;">它有三个必须的属性。<span lang="en-us" xml:lang="en-us">url</span>属性表明<span lang="en-us" xml:lang="en-us">enclosure</span>的位置，<span lang="en-us" xml:lang="en-us">length</span>属性表明它的字节大小，而<span lang="en-us" xml:lang="en-us">type</span>属性则指出它的标准<span lang="en-us" xml:lang="en-us">MIME</span>类型。<span lang="en-us" xml:lang="en-us"></span></span></span></p>
<p class="MsoNormal" style="margin:11.25pt 0cm;line-height:18pt;text-align:left;" align="left"><span style="font-family:'宋体';"><span style="font-size:medium;">这里的<span lang="en-us" xml:lang="en-us">url</span>必须为一个<span lang="en-us" xml:lang="en-us">http url</span>。</span><span style="font-size:medium;"><span lang="en-us" xml:lang="en-us"> <br />&lt;enclosure url="http://www.scripting.com/mp3s/weatherReportSuite.mp3" length="12216320" type="audio/mpeg" /&gt;<br /></span>它的<span lang="en-us" xml:lang="en-us"> use-case </span>说明请参见<span lang="en-us" xml:lang="en-us">http://www.thetwowayweb.com/payloadsforrss</span>。<span lang="en-us" xml:lang="en-us"></span></span></span></p>
<p class="MsoNormal" style="margin:11.25pt 0cm;line-height:18pt;text-align:left;" align="left"><span style="font-size:medium;"><strong><span style="font-family:'宋体';" lang="en-us" xml:lang="en-us">&lt;item&gt;</span></strong><strong><span style="font-family:'宋体';">的子元素<span lang="en-us" xml:lang="en-us">&lt;category&gt;<a href="http://www.sssdf.com/show.jsp?categoryid=2&amp;id=00012#ltcategorygtSubelementOfLtitemgt" target="_blank"></a></span></span></strong><span style="font-family:'宋体';" lang="en-us" xml:lang="en-us"></span></span></p>
<p class="MsoNormal" style="margin:11.25pt 0cm;line-height:18pt;text-align:left;" align="left"><span style="font-size:medium;"><span style="font-family:'宋体';" lang="en-us" xml:lang="en-us">&lt;category&gt;</span><span style="font-family:'宋体';">是<span lang="en-us" xml:lang="en-us">&lt;item&gt;</span>的一个可选子元素。<span lang="en-us" xml:lang="en-us"></span></span></span></p>
<p class="MsoNormal" style="margin:11.25pt 0cm;line-height:18pt;text-align:left;" align="left"><span style="font-family:'宋体';"><span style="font-size:medium;">它有一个可选属性<span lang="en-us" xml:lang="en-us">domain</span>，该属性是一个用来定义分类法的字符串。<span lang="en-us" xml:lang="en-us"></span></span></span></p>
<p class="MsoNormal" style="margin:11.25pt 0cm;line-height:18pt;text-align:left;" align="left"><span style="font-family:'宋体';"><span style="font-size:medium;">该节点的值是一个斜杠分割的字符串，它用来表明在指定的分类法中的层次位置。处理器可以为分类的识别建立协定。以下是两个例子：</span><span style="font-size:medium;"><span lang="en-us" xml:lang="en-us"> <br />&lt;category&gt;Grateful Dead&lt;/category&gt;<br />&lt;category domain="http://www.fool.com/cusips"&gt;MSFT&lt;/category&gt;<br /></span>你可以根据需要为不同的域包含很多<span lang="en-us" xml:lang="en-us">&lt;category&gt;</span>元素，并且可以在相同域的不同部分拥有一个交叉引用的<span lang="en-us" xml:lang="en-us">item</span>。<span lang="en-us" xml:lang="en-us"></span></span></span></p>
<p class="MsoNormal" style="margin:11.25pt 0cm;line-height:18pt;text-align:left;" align="left"><span style="font-size:medium;"><strong><span style="font-family:'宋体';" lang="en-us" xml:lang="en-us">&lt;item&gt;</span></strong><strong><span style="font-family:'宋体';">的子元素<span lang="en-us" xml:lang="en-us">&lt;pubDate&gt;<a href="http://www.sssdf.com/show.jsp?categoryid=2&amp;id=00012#ltpubdategtSubelementOfLtitemgt" target="_blank"></a></span></span></strong><span style="font-family:'宋体';" lang="en-us" xml:lang="en-us"></span></span></p>
<p class="MsoNormal" style="margin:11.25pt 0cm;line-height:18pt;text-align:left;" align="left"><span style="font-size:medium;"><span style="font-family:'宋体';" lang="en-us" xml:lang="en-us">&lt;pubDate&gt; </span><span style="font-family:'宋体';">是<span lang="en-us" xml:lang="en-us">&lt;item&gt;</span>的一个可选子元素。<span lang="en-us" xml:lang="en-us"></span></span></span></p>
<p class="MsoNormal" style="margin:11.25pt 0cm;line-height:18pt;text-align:left;" align="left"><span style="font-family:'宋体';"><span style="font-size:medium;">它的值是一个 日期<span lang="en-us" xml:lang="en-us">, </span>表明项目发布的时间。如果它是一个将来的日期，则聚合器在日期到达之前可以选择不显示该项目。</span><span lang="en-us" xml:lang="en-us"><span style="font-size:medium;"> <br />&lt;pubDate&gt;Sun, 19 May 2002 15:21:36 GMT&lt;/pubDate&gt;</span></span></span></p>
<p class="MsoNormal" style="margin:11.25pt 0cm;line-height:18pt;text-align:left;" align="left"><span style="font-size:medium;"><strong><span style="font-family:'宋体';" lang="en-us" xml:lang="en-us">&lt;item&gt;</span></strong><strong><span style="font-family:'宋体';">的子元素<span lang="en-us" xml:lang="en-us">&lt;guid&gt; <a href="http://www.sssdf.com/show.jsp?categoryid=2&amp;id=00012#ltguidgtSubelementOfLtitemgt" target="_blank"></a></span></span></strong><span style="font-family:'宋体';" lang="en-us" xml:lang="en-us"></span></span></p>
<p class="MsoNormal" style="margin:11.25pt 0cm;line-height:18pt;text-align:left;" align="left"><span style="font-size:medium;"><span style="font-family:'宋体';" lang="en-us" xml:lang="en-us">&lt;guid&gt;</span><span style="font-family:'宋体';">是<span lang="en-us" xml:lang="en-us">&lt;item&gt;</span>的一个可选子元素。<span lang="en-us" xml:lang="en-us"></span></span></span></p>
<p class="MsoNormal" style="margin:11.25pt 0cm;line-height:18pt;text-align:left;" align="left"><span style="font-size:medium;"><span style="font-family:'宋体';" lang="en-us" xml:lang="en-us">guid </span><span style="font-family:'宋体';">是<span lang="en-us" xml:lang="en-us"> globally unique identifier</span>的缩写。它是一个可以唯一识别这个<span lang="en-us" xml:lang="en-us">&lt;item&gt;</span>的字符串。在发布之后，聚合器可以选择使用该字符串判断这个<span lang="en-us" xml:lang="en-us">&lt;item&gt;</span>是否是新的。<span lang="en-us" xml:lang="en-us"> </span></span></span></p>
<p class="MsoNormal" style="margin:11.25pt 0cm;line-height:18pt;text-align:left;" align="left"><span style="font-size:medium;"><span style="font-family:'宋体';" lang="en-us" xml:lang="en-us">&lt;guid&gt;http://some.server.com/weblogItem3207&lt;/guid&gt;<br />guid</span><span style="font-family:'宋体';">没有特定的语法规则。聚合器必须将它们当作一个字符串来处理。生成具有唯一性的字符串<span lang="en-us" xml:lang="en-us">guid</span>取决于种子的源头。<span lang="en-us" xml:lang="en-us"></span></span></span></p>
<p class="MsoNormal" style="margin:11.25pt 0cm;line-height:18pt;text-align:left;" align="left"><span style="font-family:'宋体';"><span style="font-size:medium;">如果<span lang="en-us" xml:lang="en-us">guid</span>元素有<span lang="en-us" xml:lang="en-us">isPermaLink</span>属性，并且值为真，解释器就会认为它是<span lang="en-us" xml:lang="en-us">item</span>的<span lang="en-us" xml:lang="en-us">permalink</span>。<span lang="en-us" xml:lang="en-us">permalink</span>是一个可在<span lang="en-us" xml:lang="en-us">web</span>浏览器中打开的<span lang="en-us" xml:lang="en-us">url</span>链接，它指向<span lang="en-us" xml:lang="en-us">&lt;item&gt;</span>节点所描述的完整<span lang="en-us" xml:lang="en-us">item</span>。 例如：<span lang="en-us" xml:lang="en-us"></span></span></span></p>
<p class="MsoNormal" style="margin:11.25pt 0cm;line-height:18pt;text-align:left;" align="left"><span style="font-size:medium;"><span style="font-family:'Courier New';" lang="en-us" xml:lang="en-us">&lt;guid isPermaLink="true"&gt;http://inessential.com/2002/09/01.php#a2&lt;/guid&gt;</span><span style="font-family:'宋体';" lang="en-us" xml:lang="en-us"></span></span></p>
<p class="MsoNormal" style="margin:11.25pt 0cm;line-height:18pt;text-align:left;" align="left"><span style="font-size:medium;"><span style="font-family:'宋体';" lang="en-us" xml:lang="en-us">isPermaLink</span><span style="font-family:'宋体';">是可选属性，默认值为真。如果值为假，<span lang="en-us" xml:lang="en-us">guid</span>将不会被认为是一个<span lang="en-us" xml:lang="en-us">url</span>或指向任何对象的<span lang="en-us" xml:lang="en-us">url</span>。<span lang="en-us" xml:lang="en-us"></span></span></span></p>
<p class="MsoNormal" style="margin:11.25pt 0cm;line-height:18pt;text-align:left;" align="left"><span style="font-size:medium;"><strong><span style="font-family:'宋体';" lang="en-us" xml:lang="en-us">&lt;item&gt;</span></strong><strong><span style="font-family:'宋体';">的子元素<span lang="en-us" xml:lang="en-us">&lt;comments&gt;<a href="http://www.sssdf.com/show.jsp?categoryid=2&amp;id=00012#ltcommentsgtSubelementOfLtitemgt" target="_blank"></a></span></span></strong><span style="font-family:'宋体';" lang="en-us" xml:lang="en-us"></span></span></p>
<p class="MsoNormal" style="margin:11.25pt 0cm;line-height:18pt;text-align:left;" align="left"><span style="font-size:medium;"><span style="font-family:'宋体';" lang="en-us" xml:lang="en-us">&lt;comments&gt;</span><span style="font-family:'宋体';">是<span lang="en-us" xml:lang="en-us">&lt;item&gt;</span>的一个可选子元素。<span lang="en-us" xml:lang="en-us"></span></span></span></p>
<p class="MsoNormal" style="margin:11.25pt 0cm;line-height:18pt;text-align:left;" align="left"><span style="font-family:'宋体';"><span style="font-size:medium;">如果出现，它指向与<span lang="en-us" xml:lang="en-us">item</span>相关的评论的<span lang="en-us" xml:lang="en-us">url</span>。</span><span lang="en-us" xml:lang="en-us"><br /><span style="font-size:medium;">&lt;comments&gt;http://ekzemplo.com/entry/4403/comments&lt;/comments&gt;</span></span></span></p>
<p class="MsoNormal" style="margin:11.25pt 0cm;line-height:18pt;text-align:left;" align="left"><span style="font-size:medium;"><strong><span style="font-family:'宋体';" lang="en-us" xml:lang="en-us">&lt;item&gt;</span></strong><strong><span style="font-family:'宋体';">的子元素<span lang="en-us" xml:lang="en-us">&lt;author&gt; <a href="http://www.sssdf.com/show.jsp?categoryid=2&amp;id=00012#ltauthorgtSubelementOfLtitemgt" target="_blank"></a></span></span></strong><span style="font-family:'宋体';" lang="en-us" xml:lang="en-us"></span></span></p>
<p class="MsoNormal" style="margin:11.25pt 0cm;line-height:18pt;text-align:left;" align="left"><span style="font-size:medium;"><span style="font-family:'宋体';" lang="en-us" xml:lang="en-us">&lt;author&gt;</span><span style="font-family:'宋体';">是<span lang="en-us" xml:lang="en-us">&lt;item&gt;</span>的一个可选子元素。<span lang="en-us" xml:lang="en-us"></span></span></span></p>
<p class="MsoNormal" style="margin:11.25pt 0cm;line-height:18pt;text-align:left;" align="left"><span style="font-family:'宋体';"><span style="font-size:medium;">它是<span lang="en-us" xml:lang="en-us">item</span>作者的电子邮件地址<span lang="en-us" xml:lang="en-us">l</span>。对于通过<span lang="en-us" xml:lang="en-us">rss</span>传播的报纸和杂志，作者可能是写该<span lang="en-us" xml:lang="en-us">item</span>所描述的文章的人。对于聚集型<span lang="en-us" xml:lang="en-us">webblogs</span>，作者可能不是责任编辑或站长。对于个人维护的<span lang="en-us" xml:lang="en-us">webblog</span>，忽略<span lang="en-us" xml:lang="en-us">&lt;author&gt;</span>节点是有意义的。<span lang="en-us" xml:lang="en-us"></span></span></span></p>
<p class="MsoNormal" style="margin:11.25pt 0cm;line-height:18pt;text-align:left;" align="left"><span style="font-family:'宋体';" lang="en-us" xml:lang="en-us"><span style="font-size:medium;">&lt;author&gt;lawyer@boyer.net (Lawyer Boyer)&lt;/author&gt;</span></span></p>
<p class="MsoNormal" style="margin:11.25pt 0cm 11.25pt 21pt;text-indent:-21pt;line-height:18pt;text-align:left;" align="left"><span style="font-size:medium;"><span style="font-family:'宋体';" lang="en-us" xml:lang="en-us"><span>七、</span></span><strong><span style="font-family:'宋体';">注释<span lang="en-us" xml:lang="en-us"><a href="http://www.sssdf.com/show.jsp?categoryid=2&amp;id=00012#comments" target="_blank"></a></span></span></strong><span style="font-family:'宋体';" lang="en-us" xml:lang="en-us"></span></span></p>
<p class="MsoNormal" style="margin:11.25pt 0cm;line-height:18pt;text-align:left;" align="left"><span style="font-size:medium;"><span style="font-family:'宋体';" lang="en-us" xml:lang="en-us">RSS</span><span style="font-family:'宋体';">限制<span lang="en-us" xml:lang="en-us">&lt;link&gt; </span>和<span lang="en-us" xml:lang="en-us"> &lt;url&gt;</span>元素的数据首字母为非空格字符。这些元素的数据必须以<span lang="en-us" xml:lang="en-us">IANA-registered URI</span>方案规定的格式开始，如<span lang="en-us" xml:lang="en-us">http://, https://, news://, mailto:</span>和<span lang="en-us" xml:lang="en-us"> ftp://</span>等。在<span lang="en-us" xml:lang="en-us">RSS2.0</span>规范之前，<span lang="en-us" xml:lang="en-us">RSS</span>规范只允许<span lang="en-us" xml:lang="en-us">http:// </span>和<span lang="en-us" xml:lang="en-us"> ftp://</span>，然而在实践中，其他的<span lang="en-us" xml:lang="en-us">URI</span>方案被内容开发者广泛使用，并被聚合器所支持。聚合器也许对它们支持的<span lang="en-us" xml:lang="en-us">URI</span>方案有一些限制，而内容开发者不应该假定所有的聚合器都支持所有的<span lang="en-us" xml:lang="en-us">URI</span>方案。<span lang="en-us" xml:lang="en-us"></span></span></span></p>
<p class="MsoNormal" style="margin:11.25pt 0cm;line-height:18pt;text-align:left;" align="left"><span style="font-family:'宋体';"><span style="font-size:medium;">在<span lang="en-us" xml:lang="en-us"> RSS 0.91</span>规范中，各种元素都被限制为<span lang="en-us" xml:lang="en-us">500</span>或<span lang="en-us" xml:lang="en-us">100</span>个字符。在一个符合<span lang="en-us" xml:lang="en-us">0.91</span>规范的频道中，不能超过<span lang="en-us" xml:lang="en-us">15</span>个<span lang="en-us" xml:lang="en-us"> &lt;item&gt; </span>元素。在<span lang="en-us" xml:lang="en-us">RSS 0.92</span>和以后的规范中，不再有这些字符长度或者<span lang="en-us" xml:lang="en-us">XML</span>级别的限制。处理器也许强加一些它们自己的限制，产生者也许有自己的一些参数选择，它们可以规定在一个频道中，不超过一定数目的<span lang="en-us" xml:lang="en-us">&lt;item&gt;</span>元素，或者字符串都限制在一定的长度。<span lang="en-us" xml:lang="en-us"> </span></span></span></p>
<p class="MsoNormal" style="margin:11.25pt 0cm;line-height:18pt;text-align:left;" align="left"><span style="font-family:'宋体';"><span style="font-size:medium;">如上所述，在<span lang="en-us" xml:lang="en-us"> RSS 2.0</span>规范中，对于一个目录系统，当链接一个频道到它的标识中时，使用基于频道级别的分类特征。 例如，如果链接一个频道到它的<span lang="en-us" xml:lang="en-us">Syndic8 </span>标识，则将包括一个分类元素作为频道的子元素，它有域<span lang="en-us" xml:lang="en-us">“Syndic8”</span>属性，同时在<span lang="en-us" xml:lang="en-us">Syndic8 </span>数据库中为你的频道确定这个标识。正确的分类元素脚本应该是<span lang="en-us" xml:lang="en-us"> &lt;category domain="Syndic8"&gt;1765&lt;/category&gt;</span>。<span lang="en-us" xml:lang="en-us"></span></span></span></p>
<p class="MsoNormal" style="margin:11.25pt 0cm;line-height:18pt;text-align:left;" align="left"><span style="font-family:'宋体';"><span style="font-size:medium;">一个经常被问到的问题是关于<span lang="en-us" xml:lang="en-us">&lt;guid&gt; </span>如何和<span lang="en-us" xml:lang="en-us"> &lt;link&gt;</span>进行区别。它们指的是相同的事情吗？在一些内容系统中是，但在别的内容系统中可能不是。在一些系统中，<span lang="en-us" xml:lang="en-us">&lt;link&gt;</span>是一个网络日志项的永久链接。然后在别的系统中，每一个<span lang="en-us" xml:lang="en-us">&lt;item&gt;</span>都是一个较长文章的摘要，<span lang="en-us" xml:lang="en-us">&lt;link&gt;</span>指向这篇文章，而<span lang="en-us" xml:lang="en-us">&lt;guid&gt;</span>则是这个网络日志入口的永久链接。在所有的情况下，建议提供<span lang="en-us" xml:lang="en-us">&lt;guid&gt;,</span>如果可能的话，并使它成为一个永久链接。这使聚合着在内容发生变化时，也不会出现重复项目成为可能。<span lang="en-us" xml:lang="en-us"></span></span></span></p>
<p class="MsoNormal" style="margin:11.25pt 0cm;line-height:18pt;text-align:left;" align="left"><span style="font-family:'宋体';"><span style="font-size:medium;">如果你对<span lang="en-us" xml:lang="en-us">RSS 2.0</span>规范的格式有任何问题，请向由<span lang="en-us" xml:lang="en-us">Sjoerd Visscher</span>维护的电子邮件列表<span lang="en-us" xml:lang="en-us">RSS2-Support</span>发送邮件。这个邮件列表不是一个技术辩论的列表，而是一个针对作者和开发人员在创建和使用<span lang="en-us" xml:lang="en-us">RSS 2.0</span>格式的内容时提供技术支持的列表。<span lang="en-us" xml:lang="en-us"></span></span></span></p>
<p class="MsoNormal" style="margin:11.25pt 0cm 11.25pt 21pt;text-indent:-21pt;line-height:18pt;text-align:left;" align="left"><span style="font-size:medium;"><span style="font-family:'宋体';" lang="en-us" xml:lang="en-us"><span>八、</span></span><strong><span style="font-family:'宋体';" lang="en-us" xml:lang="en-us">RSS</span></strong><strong><span style="font-family:'宋体';">的扩展<span lang="en-us" xml:lang="en-us"><a href="http://www.sssdf.com/show.jsp?categoryid=2&amp;id=00012#extendingRss" target="_blank"></a></span></span></strong><span style="font-family:'宋体';" lang="en-us" xml:lang="en-us"></span></span></p>
<p class="MsoNormal" style="margin:0cm 0cm 0pt;line-height:18pt;text-align:left;" align="left"><span style="font-size:medium;"><span style="font-family:'宋体';" lang="en-us" xml:lang="en-us">RSS</span><span style="font-family:'宋体';">起源于<span lang="en-us" xml:lang="en-us">1999</span>年，目标是成为一个简单、易于理解的数据格式。在它逐渐成为一种流行格式之后，开发者想在一个名字空间中使用模块对它进行扩展，正像<span lang="en-us" xml:lang="en-us">W3C<a href="http://www.w3.org/TR/REC-xml-names/" target="_blank"><strong><span style="color:#920011;text-decoration:none;" lang="en-us" xml:lang="en-us"><span lang="en-us" xml:lang="en-us">定义</span></span></strong></a></span>的那样。<span lang="en-us" xml:lang="en-us"></span></span></span></p>
<p class="MsoNormal" style="margin:11.25pt 0cm;line-height:18pt;text-align:left;" align="left"><span style="font-size:medium;"><span style="font-family:'宋体';" lang="en-us" xml:lang="en-us">RSS</span><span style="font-family:'宋体';">遵循简单的规则，增加了它的能力。一个<span lang="en-us" xml:lang="en-us">RSS feed </span>可以包含不是在本页中描述的内容，而只是在一个名字空间中定义的那些元素。<span lang="en-us" xml:lang="en-us"></span></span></span></p>
<p class="MsoNormal" style="margin:11.25pt 0cm;line-height:18pt;text-align:left;" align="left"><span style="font-family:'宋体';"><span style="font-size:medium;">本文档中定义的元素不是一个名字空间本省的元素，因此，<span lang="en-us" xml:lang="en-us"> RSS2.0</span>从某种意义上来讲，和原来的版本是兼容的，即一个<span lang="en-us" xml:lang="en-us"> 0.91 </span>或者<span lang="en-us" xml:lang="en-us"> 0.92 </span>版本的文件也是一个有效的<span lang="en-us" xml:lang="en-us"> 2.0 </span>版本文件。如果<span lang="en-us" xml:lang="en-us">RSS2.0</span>的元素是在一个名字空间中，那么这种约束将被打破，即 一个<span lang="en-us" xml:lang="en-us">0.9x </span>版本的文件不可能是一个有效的<span lang="en-us" xml:lang="en-us">2.0 </span>版本的文件。<span lang="en-us" xml:lang="en-us"></span></span></span></p>
<p class="MsoNormal" style="margin:11.25pt 0cm 11.25pt 21pt;text-indent:-21pt;line-height:18pt;text-align:left;" align="left"><a name="roadmap"><span style="font-size:medium;"><span style="font-family:'宋体';" lang="en-us" xml:lang="en-us"><span>九、</span></span><strong><span style="font-family:'宋体';">展望<span lang="en-us" xml:lang="en-us"> </span></span></strong></span></a><span style="font-family:'宋体';" lang="en-us" xml:lang="en-us"></span></p>
<p class="MsoNormal" style="margin:11.25pt 0cm;line-height:18pt;text-align:left;" align="left"><span style="font-size:medium;"><span style="font-family:'宋体';" lang="en-us" xml:lang="en-us">RSS</span><span style="font-family:'宋体';">决不是一个完美的格式，但是它现在已经非常流行，并得到广泛的支持。要成为一个固定的规范，<span lang="en-us" xml:lang="en-us">RSS</span>需要很长的一段时间。这项工作的目的是帮助<span lang="en-us" xml:lang="en-us">RSS</span>成为一个固定的事情，同时促进和培育围绕它进行的开发的市场的增长，并为新的聚合格式铺平道路。因此，为了实用的目的，<span lang="en-us" xml:lang="en-us">RSS</span>规范将被冻结在<span lang="en-us" xml:lang="en-us">2.0.2</span>版本。我们可以预期的可能的<span lang="en-us" xml:lang="en-us">2.0.2 </span>或者<span lang="en-us" xml:lang="en-us"> 2.0.3</span>等版本，都只是出于澄清规范的目的，而不是在格式上增加新的特征。后续的工作应该集中在模块化、名字空间的使用和在完全新的聚合格式中用新的名字等方面。<span lang="en-us" xml:lang="en-us"></span></span></span></p>
<p class="MsoNormal" style="margin:11.25pt 0cm 11.25pt 21pt;text-indent:-21pt;line-height:18pt;text-align:left;" align="left"><span style="font-size:medium;"><span style="font-family:'宋体';" lang="en-us" xml:lang="en-us"><span>十、</span></span><strong><span style="font-family:'宋体';">许可协议和作者<span lang="en-us" xml:lang="en-us"><a href="http://www.sssdf.com/show.jsp?categoryid=2&amp;id=00012#licenseAndAuthorship" target="_blank"></a></span></span></strong><span style="font-family:'宋体';" lang="en-us" xml:lang="en-us"></span></span></p>
<p class="MsoNormal" style="margin:11.25pt 0cm;line-height:18pt;text-align:left;" align="left"><span style="font-size:medium;"><span style="font-family:'宋体';" lang="en-us" xml:lang="en-us">RSS 2.0 </span><span style="font-family:'宋体';">是在遵循<span lang="en-us" xml:lang="en-us">i the Attribution/Share Alike Creative Commons </span>许可协议<span lang="en-us" xml:lang="en-us"> </span>的基础上由<span lang="en-us" xml:lang="en-us"> the Berkman Center for Internet &amp; Society at Harvard Law School </span>提供。本文档的作者是<span lang="en-us" xml:lang="en-us"> Dave Winer</span>，<span lang="en-us" xml:lang="en-us">UserLand software</span>的创始人，也是<span lang="en-us" xml:lang="en-us"> Berkman Center </span>的员工。<span lang="en-us" xml:lang="en-us"></span></span></span></p>
<p class="MsoNormal" style="margin:0cm 0cm 0pt;"><span lang="en-us" xml:lang="en-us"><span style="font-size:medium;font-family:'Times New Roman';"> </span></span></p><p><a href="http://www.yeeyan.com/articles/view/75374/34444#newComment">添加评论</a></p>
<p><embed id="movie_rss" height="60" width="468" quality="high" bgcolor="#ffffff" name="mymovie" style="" src="http://www.yeeyan.com/files/newindexads/vancl_090622_468_rss.swf" type="application/x-shockwave-flash"/></p>
]]>
        </content>
    <feedburner:origLink>http://www.yeeyan.com/articles/view/75374/34444</feedburner:origLink></entry>
</feed>
