<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Wut I am &#187; Development</title>
	<atom:link href="http://wutiam.net/category/development/feed/" rel="self" type="application/rss+xml" />
	<link>http://wutiam.net</link>
	<description>I'm islet8, I'm what I am</description>
	<lastBuildDate>Wed, 28 Jul 2010 02:50:02 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>避免在 C++ 类结构中出现私有虚成员函数</title>
		<link>http://wutiam.net/2010/07/avoid-private-virtual-member-function-in-cpp-class/</link>
		<comments>http://wutiam.net/2010/07/avoid-private-virtual-member-function-in-cpp-class/#comments</comments>
		<pubDate>Tue, 27 Jul 2010 12:34:44 +0000</pubDate>
		<dc:creator>islet8</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[c++]]></category>

		<guid isPermaLink="false">http://wutiam.net/?p=134</guid>
		<description><![CDATA[最近在重构 C++ 代码时突然想起，如果一个基类的虚成员函数被设为 private，有没有意义？又是否合理？
当然，有其一定的意义，那就是不希望子类在其他地方调用父类的这个函数，包括在子类的实现中；如果需要这个功能，应该使用其 public 的接口去使用该功能。而子类可以提供自己的实现，以提供多态。但是，如果子类觉得需要，还可以把这个 private 的虚成员函数重定义成 protected（虽然这会让人迷惑），从而使子类的子类们调用它。
有同学可能会问，如果是一个 private 的纯虚成员函数（语法上当然合理），那语义合理么？嗯，我觉得这的确是个问题——也许是为了告诉写子类的其他同学，这个虚函数，我不希望你们在除了基类已有的接口里调用之外还来用——仅仅是一个道德约束？！
嗯，C++ 就是灵活得过头了，什么都让程序员自己去把控，可是别忘了，“太多的选择比没有选择糟糕得多”。所以，我决定，为了自己也为了别人不犯迷糊，避免使用 private 的虚函数，private 的成员函数仅包含当前类自己使用的函数。
BTW，类的成员变量正好相反，能设为 private 的尽量不要 protected 更不要public，否则后期维护，嗯嗯，就太痛苦了。


Related posts:乱用 STL 是地狱
do...while(0) 的妙用
让 C++ 的 new 操作失败时返回空指针



Related posts:<ul><li><a href='http://wutiam.net/2010/04/stl-on-the-wrong-way-may-lead-to-hell/' rel='bookmark' title='Permanent Link: 乱用 STL 是地狱'>乱用 STL 是地狱</a></li>
<li><a href='http://wutiam.net/2010/03/ingenious-usage-of-do-while-0/' rel='bookmark' title='Permanent Link: do...while(0) 的妙用'>do...while(0) 的妙用</a></li>
<li><a href='http://wutiam.net/2010/02/let-cpp-new-operator-return-null-when-failed/' rel='bookmark' title='Permanent Link: 让 C++ 的 new 操作失败时返回空指针'>让 C++ 的 new 操作失败时返回空指针</a></li>
</ul>]]></description>
			<content:encoded><![CDATA[<p>最近在重构 C++ 代码时突然想起，如果一个基类的虚成员函数被设为 private，有没有意义？又是否合理？</p>
<p>当然，有其一定的意义，那就是不希望子类在其他地方调用父类的这个函数，包括在子类的实现中；如果需要这个功能，应该使用其 public 的接口去使用该功能。而子类可以提供自己的实现，以提供多态。但是，如果子类觉得需要，还可以把这个 private 的虚成员函数重定义成 protected（虽然这会让人迷惑），从而使子类的子类们调用它。</p>
<p>有同学可能会问，如果是一个 private 的纯虚成员函数（语法上当然合理），那语义合理么？嗯，我觉得这的确是个问题——也许是为了告诉写子类的其他同学，这个虚函数，我不希望你们在除了基类已有的接口里调用之外还来用——仅仅是一个道德约束？！</p>
<p>嗯，C++ 就是灵活得过头了，什么都让程序员自己去把控，可是别忘了，“太多的选择比没有选择糟糕得多”。所以，我决定，为了自己也为了别人不犯迷糊，避免使用 private 的虚函数，private 的成员函数仅包含当前类自己使用的函数。</p>
<p>BTW，类的成员变量正好相反，能设为 private 的尽量不要 protected 更不要public，否则后期维护，嗯嗯，就太痛苦了。</p>


<p>Related posts:<ul><li><a href='http://wutiam.net/2010/04/stl-on-the-wrong-way-may-lead-to-hell/' rel='bookmark' title='Permanent Link: 乱用 STL 是地狱'>乱用 STL 是地狱</a></li>
<li><a href='http://wutiam.net/2010/03/ingenious-usage-of-do-while-0/' rel='bookmark' title='Permanent Link: do...while(0) 的妙用'>do...while(0) 的妙用</a></li>
<li><a href='http://wutiam.net/2010/02/let-cpp-new-operator-return-null-when-failed/' rel='bookmark' title='Permanent Link: 让 C++ 的 new 操作失败时返回空指针'>让 C++ 的 new 操作失败时返回空指针</a></li>
</ul></p>]]></content:encoded>
			<wfw:commentRss>http://wutiam.net/2010/07/avoid-private-virtual-member-function-in-cpp-class/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>VS2010 中的 C++ 0x 新特性：Lambdas、auto 和 static_assert</title>
		<link>http://wutiam.net/2010/06/lambdas-auto-and-static-assert-c-0x-features-in-vc10/</link>
		<comments>http://wutiam.net/2010/06/lambdas-auto-and-static-assert-c-0x-features-in-vc10/#comments</comments>
		<pubDate>Tue, 01 Jun 2010 09:59:39 +0000</pubDate>
		<dc:creator>islet8</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[vs/vc++]]></category>

		<guid isPermaLink="false">http://wutiam.net/?p=132</guid>
		<description><![CDATA[转载自痴痴笑笑的博客，略有删改。
尽管 C++ 社区对 C++ 0x 很是追捧，但是各厂商对于新标准的支持并不热乎。盼星星盼月亮，微软作为 Windows 平台上最强势的 C++ 编译器厂商也终于在 Visual Studio 2010 中开始支持 C++ 0x 的特性。
Visual Studio 2010 中的 Visual C++ 编译器，即 VC10, 包含了 4 个 C++ 0x 的语言特性：lambda 表达式，自动类型推演（auto 关键字），静态断言（static_assert）和右值引用（rvalue reference）。

Lambda 表达式
使用过函数式编程语言（如 LISP、 F#）或一些动态语言（如 Python、Javascript）的大侠对于 lambda 表达式一定不会陌生。在 C++ 0x 中，引入了 lambda 表达式来定义无名仿函数。下面是一个 lambda 表达式的简单例子：

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include &#60;algorithm&#62;
#include &#60;iostream&#62;
#include &#60;ostream&#62;
#include &#60;vector&#62;
&#160;
using namespace std;
&#160;
int main&#40;&#41; &#123;
  [...]


Related posts:<ul><li><a href='http://wutiam.net/2009/06/uninstalling-visual-studio-2008-may-fail-to-load-setup-components/' rel='bookmark' title='Permanent Link: Visual Studio 2008 无法进入修复/卸载界面的解决办法'>Visual Studio 2008 无法进入修复/卸载界面的解决办法</a></li>
<li><a href='http://wutiam.net/2009/05/ctreectrl-traversal/' rel='bookmark' title='Permanent Link: 遍历 CTreeCtrl'>遍历 CTreeCtrl</a></li>
<li><a href='http://wutiam.net/2009/04/some-vs2005-and-vs2008-wizards-pop-up-script-error/' rel='bookmark' title='Permanent Link: IE8 引发 VS 2005/2008 向导出错的解决方案'>IE8 引发 VS 2005/2008 向导出错的解决方案</a></li>
</ul>]]></description>
			<content:encoded><![CDATA[<p>转载自<a href="http://www.cnblogs.com/brucejia/" target="_blank">痴痴笑笑的博客</a>，略有删改。</p>
<p>尽管 C++ 社区对 C++ 0x 很是追捧，但是各厂商对于新标准的支持并不热乎。盼星星盼月亮，微软作为 Windows 平台上最强势的 C++ 编译器厂商也终于在 Visual Studio 2010 中开始支持 C++ 0x 的特性。</p>
<p>Visual Studio 2010 中的 Visual C++ 编译器，即 VC10, 包含了 4 个 C++ 0x 的语言特性：lambda 表达式，自动类型推演（auto 关键字），静态断言（static_assert）和右值引用（rvalue reference）。<br />
<span id="more-132"></span></p>
<h3>Lambda 表达式</h3>
<p>使用过函数式编程语言（如 LISP、 F#）或一些动态语言（如 Python、Javascript）的大侠对于 lambda 表达式一定不会陌生。在 C++ 0x 中，引入了 lambda 表达式来定义无名仿函数。下面是一个 lambda 表达式的简单例子：</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
</pre></td><td class="code"><pre class="cpp" style="font-family:monospace;"><span style="color: #339900;">#include &lt;algorithm&gt;</span>
<span style="color: #339900;">#include &lt;iostream&gt;</span>
<span style="color: #339900;">#include &lt;ostream&gt;</span>
<span style="color: #339900;">#include &lt;vector&gt;</span>
&nbsp;
<span style="color: #0000ff;">using</span> <span style="color: #0000ff;">namespace</span> std<span style="color: #008080;">;</span>
&nbsp;
<span style="color: #0000ff;">int</span> main<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
    vector<span style="color: #000080;">&lt;</span><span style="color: #0000ff;">int</span><span style="color: #000080;">&gt;</span> v<span style="color: #008080;">;</span>
&nbsp;
    <span style="color: #0000ff;">for</span> <span style="color: #008000;">&#40;</span><span style="color: #0000ff;">int</span> i <span style="color: #000080;">=</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span> i <span style="color: #000080;">&lt;</span> <span style="color: #0000dd;">10</span><span style="color: #008080;">;</span> <span style="color: #000040;">++</span>i<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
        v.<span style="color: #007788;">push_back</span><span style="color: #008000;">&#40;</span>i<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #008000;">&#125;</span>
&nbsp;
    for_each<span style="color: #008000;">&#40;</span>v.<span style="color: #007788;">begin</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>, v.<span style="color: #007788;">end</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>, <span style="color: #008000;">&#91;</span><span style="color: #008000;">&#93;</span><span style="color: #008000;">&#40;</span><span style="color: #0000ff;">int</span> n<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span> <span style="color: #0000dd;">cout</span> <span style="color: #000080;">&lt;&lt;</span> n <span style="color: #000080;">&lt;&lt;</span> <span style="color: #FF0000;">&quot; &quot;</span><span style="color: #008080;">;</span> <span style="color: #008000;">&#125;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000dd;">cout</span> <span style="color: #000080;">&lt;&lt;</span> endl<span style="color: #008080;">;</span>
&nbsp;
    <span style="color: #0000ff;">return</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

<p>运行结果如下：</p>

<div class="wp_syntax"><div class="code"><pre class="txt" style="font-family:monospace;">0 1 2 3 4 5 6 7 8 9</pre></div></div>

<p>for_each 一行中，中括号 [] 称为 lambda introducer，它告诉编译器接下来的是一个 lambda 表达式；接下来 (int n) 是 lambda 表达式的参数声明；最后大括号里边就是“函数体”了。</p>
<p>注意这里因为 lambda 表达式生成的是 functor，所以“函数体”实际上是指这个 functor 的 operator() 的调用部分。你也许会问：那么返回值呢？缺省情况下 lambda 表达式生成的 functor 调用返回类型为 void。</p>
<p>为了方便，以下会用“lambda 返回 void”的简短表述来代替冗长啰嗦的表述—— lambda 表达式生成一个 functor 类型，这个 functor 类型的函数调用操作符（operator()），返回的类型是 void。<br />
请大家一定记住：lambda 表达式生成了类型，并构造该类型的实例。</p>
<p>下面的例子中 lambda 表达式的“函数体”包含多条语句：</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
</pre></td><td class="code"><pre class="cpp" style="font-family:monospace;"><span style="color: #339900;">#include &lt;algorithm&gt;</span>
<span style="color: #339900;">#include &lt;iostream&gt;</span>
<span style="color: #339900;">#include &lt;ostream&gt;</span>
<span style="color: #339900;">#include &lt;vector&gt;</span>
&nbsp;
<span style="color: #0000ff;">using</span> <span style="color: #0000ff;">namespace</span> std<span style="color: #008080;">;</span>
&nbsp;
<span style="color: #0000ff;">int</span> main<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
    vector<span style="color: #000080;">&lt;</span><span style="color: #0000ff;">int</span><span style="color: #000080;">&gt;</span> v<span style="color: #008080;">;</span>
    <span style="color: #0000ff;">for</span> <span style="color: #008000;">&#40;</span><span style="color: #0000ff;">int</span> i <span style="color: #000080;">=</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span> i <span style="color: #000080;">&lt;</span> <span style="color: #0000dd;">10</span><span style="color: #008080;">;</span> <span style="color: #000040;">++</span>i<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
        v.<span style="color: #007788;">push_back</span><span style="color: #008000;">&#40;</span>i<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #008000;">&#125;</span>
&nbsp;
    for_each<span style="color: #008000;">&#40;</span>v.<span style="color: #007788;">begin</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>, v.<span style="color: #007788;">end</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>, <span style="color: #008000;">&#91;</span><span style="color: #008000;">&#93;</span><span style="color: #008000;">&#40;</span><span style="color: #0000ff;">int</span> n<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
        <span style="color: #0000dd;">cout</span> <span style="color: #000080;">&lt;&lt;</span> n<span style="color: #008080;">;</span>
&nbsp;
        <span style="color: #0000ff;">if</span> <span style="color: #008000;">&#40;</span>n <span style="color: #000040;">%</span> <span style="color: #0000dd;">2</span> <span style="color: #000080;">==</span> <span style="color: #0000dd;">0</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
            <span style="color: #0000dd;">cout</span> <span style="color: #000080;">&lt;&lt;</span> <span style="color: #FF0000;">&quot; even &quot;</span><span style="color: #008080;">;</span>
        <span style="color: #008000;">&#125;</span> <span style="color: #0000ff;">else</span> <span style="color: #008000;">&#123;</span>
            <span style="color: #0000dd;">cout</span> <span style="color: #000080;">&lt;&lt;</span> <span style="color: #FF0000;">&quot; odd &quot;</span><span style="color: #008080;">;</span>
        <span style="color: #008000;">&#125;</span>
    <span style="color: #008000;">&#125;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000dd;">cout</span> <span style="color: #000080;">&lt;&lt;</span> endl<span style="color: #008080;">;</span>
&nbsp;
    <span style="color: #0000ff;">return</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

<p>上文提到了 lambda 表达式缺省情况下返回 void，那么如果需要返回其他类型呢？答案是：lambda 表达式的“函数体”中如果有一个 return 的表达式，例如 { return expression; }，那么编译器将自动推演 expression 的类型作为返回类型。</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
</pre></td><td class="code"><pre class="cpp" style="font-family:monospace;"><span style="color: #339900;">#include &lt;algorithm&gt;</span>
<span style="color: #339900;">#include &lt;deque&gt;</span>
<span style="color: #339900;">#include &lt;iostream&gt;</span>
<span style="color: #339900;">#include &lt;iterator&gt;</span>
<span style="color: #339900;">#include &lt;ostream&gt;</span>
<span style="color: #339900;">#include &lt;vector&gt;</span>
&nbsp;
<span style="color: #0000ff;">using</span> <span style="color: #0000ff;">namespace</span> std<span style="color: #008080;">;</span>
&nbsp;
<span style="color: #0000ff;">int</span> main<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
    vector<span style="color: #000080;">&lt;</span><span style="color: #0000ff;">int</span><span style="color: #000080;">&gt;</span> v<span style="color: #008080;">;</span>
&nbsp;
    <span style="color: #0000ff;">for</span> <span style="color: #008000;">&#40;</span><span style="color: #0000ff;">int</span> i <span style="color: #000080;">=</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span> i <span style="color: #000080;">&lt;</span> <span style="color: #0000dd;">10</span><span style="color: #008080;">;</span> <span style="color: #000040;">++</span>i<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
        v.<span style="color: #007788;">push_back</span><span style="color: #008000;">&#40;</span>i<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #008000;">&#125;</span>
&nbsp;
    deque<span style="color: #000080;">&lt;</span><span style="color: #0000ff;">int</span><span style="color: #000080;">&gt;</span> d<span style="color: #008080;">;</span>
&nbsp;
    transform<span style="color: #008000;">&#40;</span>v.<span style="color: #007788;">begin</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>, v.<span style="color: #007788;">end</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>, front_inserter<span style="color: #008000;">&#40;</span>d<span style="color: #008000;">&#41;</span>, <span style="color: #008000;">&#91;</span><span style="color: #008000;">&#93;</span><span style="color: #008000;">&#40;</span><span style="color: #0000ff;">int</span> n<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span> <span style="color: #0000ff;">return</span> n <span style="color: #000040;">*</span> n <span style="color: #000040;">*</span> n<span style="color: #008080;">;</span> <span style="color: #008000;">&#125;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
&nbsp;
    for_each<span style="color: #008000;">&#40;</span>d.<span style="color: #007788;">begin</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>, d.<span style="color: #007788;">end</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>, <span style="color: #008000;">&#91;</span><span style="color: #008000;">&#93;</span><span style="color: #008000;">&#40;</span><span style="color: #0000ff;">int</span> n<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span> <span style="color: #0000dd;">cout</span> <span style="color: #000080;">&lt;&lt;</span> n <span style="color: #000080;">&lt;&lt;</span> <span style="color: #FF0000;">&quot; &quot;</span><span style="color: #008080;">;</span> <span style="color: #008000;">&#125;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000dd;">cout</span> <span style="color: #000080;">&lt;&lt;</span> endl<span style="color: #008080;">;</span>
&nbsp;
    <span style="color: #0000ff;">return</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

<p>上例中返回值 n * n * n 很简单，类型推演是显而易见的。但是如果 lambda 表达式中有非常复杂的表达式时，编译器可能无法推演出其类型，或者是推演出现二义性，这时候你可以显式地指明返回值类型。如下所示：</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
</pre></td><td class="code"><pre class="cpp" style="font-family:monospace;">transform<span style="color: #008000;">&#40;</span>v.<span style="color: #007788;">begin</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>, v.<span style="color: #007788;">end</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>, front_inserter<span style="color: #008000;">&#40;</span>d<span style="color: #008000;">&#41;</span>, <span style="color: #008000;">&#91;</span><span style="color: #008000;">&#93;</span><span style="color: #008000;">&#40;</span><span style="color: #0000ff;">int</span> n<span style="color: #008000;">&#41;</span> <span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span> <span style="color: #0000ff;">double</span> <span style="color: #008000;">&#123;</span>
    <span style="color: #0000ff;">if</span> <span style="color: #008000;">&#40;</span>n <span style="color: #000040;">%</span> <span style="color: #0000dd;">2</span> <span style="color: #000080;">==</span> <span style="color: #0000dd;">0</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
        <span style="color: #0000ff;">return</span> n <span style="color: #000040;">*</span> n <span style="color: #000040;">*</span> n<span style="color: #008080;">;</span>
    <span style="color: #008000;">&#125;</span> <span style="color: #0000ff;">else</span> <span style="color: #008000;">&#123;</span>
        <span style="color: #0000ff;">return</span> n <span style="color: #000040;">/</span> <span style="color:#800080;">2.0</span><span style="color: #008080;">;</span>
    <span style="color: #008000;">&#125;</span>
<span style="color: #008000;">&#125;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span></pre></td></tr></table></div>

<p>“-> double”显式地指明了 lambda 表达式的返回类型是 double。</p>
<p>以上例子中的 lambda 都是无状态的，不包含任何数据成员。很多时候我们需要 lambda 包含数据成员以保存状态，这一点可以通过“捕获”局部变量来实现。</p>
<p>Lambda 表达式的导入符（lambda introducer）是空的，也就是“[]”，表明该 lambda 是一个无状态的。但是在 lambda导入符中可以指定一个“捕获列表”，下面的代码中的 lambda 使用了局部变量 x 和 y，将值介于 x 和 y 之间的元素从集合中删除：</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
</pre></td><td class="code"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">int</span> main<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
    vector<span style="color: #000080;">&lt;</span><span style="color: #0000ff;">int</span><span style="color: #000080;">&gt;</span> v<span style="color: #008080;">;</span>
    <span style="color: #0000ff;">for</span> <span style="color: #008000;">&#40;</span><span style="color: #0000ff;">int</span> i <span style="color: #000080;">=</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span> i <span style="color: #000080;">&lt;</span> <span style="color: #0000dd;">10</span><span style="color: #008080;">;</span> <span style="color: #000040;">++</span>i<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
        v.<span style="color: #007788;">push_back</span><span style="color: #008000;">&#40;</span>i<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #008000;">&#125;</span>
&nbsp;
    <span style="color: #0000ff;">int</span> x <span style="color: #000080;">=</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">int</span> y <span style="color: #000080;">=</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span>
&nbsp;
    <span style="color: #0000dd;">cout</span> <span style="color: #000080;">&lt;&lt;</span> <span style="color: #FF0000;">&quot;Input: &quot;</span><span style="color: #008080;">;</span>
    <span style="color: #0000dd;">cin</span> <span style="color: #000080;">&gt;&gt;</span> x <span style="color: #000080;">&gt;&gt;</span> y<span style="color: #008080;">;</span>
    v.<span style="color: #007788;">erase</span><span style="color: #008000;">&#40;</span>remove_if<span style="color: #008000;">&#40;</span>v.<span style="color: #007788;">begin</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>, v.<span style="color: #007788;">end</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>, <span style="color: #008000;">&#91;</span>x, y<span style="color: #008000;">&#93;</span><span style="color: #008000;">&#40;</span><span style="color: #0000ff;">int</span> n<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span> <span style="color: #0000ff;">return</span> x <span style="color: #000080;">&lt;</span> n <span style="color: #000040;">&amp;&amp;</span> n <span style="color: #000080;">&lt;</span> y<span style="color: #008080;">;</span> <span style="color: #008000;">&#125;</span><span style="color: #008000;">&#41;</span>, v.<span style="color: #007788;">end</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    for_each<span style="color: #008000;">&#40;</span>v.<span style="color: #007788;">begin</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>, v.<span style="color: #007788;">end</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>, <span style="color: #008000;">&#91;</span><span style="color: #008000;">&#93;</span><span style="color: #008000;">&#40;</span><span style="color: #0000ff;">int</span> n<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span> <span style="color: #0000dd;">cout</span> <span style="color: #000080;">&lt;&lt;</span> n <span style="color: #000080;">&lt;&lt;</span> <span style="color: #FF0000;">&quot; &quot;</span><span style="color: #008080;">;</span> <span style="color: #008000;">&#125;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000dd;">cout</span> <span style="color: #000080;">&lt;&lt;</span> endl<span style="color: #008080;">;</span>
&nbsp;
    <span style="color: #0000ff;">return</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

<p>运行结果如下：</p>

<div class="wp_syntax"><div class="code"><pre class="txt" style="font-family:monospace;">Input: 4 7
0 1 2 3 4 7 8 9</pre></div></div>

<p>上面代码中很重要的一点信息是：lambda 中捕获的局部变量是以“传值”的方式传给匿名函数对象的。在匿名函数对象中，保存有“捕获列表”中局部变量的拷贝。这一点使得匿名函数对象的生命周期能够长于 main 中的 x、y 局部变量。然而这样的传值方式带来几个限制：</p>
<ol>
<li>lambda中的这两个拷贝并不能被改变，因为缺省情况下函数对象的 operator() 是const</li>
<li>有的对象的拷贝操作开销很大或者不可能（例如如果上面代码中的 x、y 是数据库链接或者某个 singleton）</li>
<li>即使在lambda内部修改了 m_a、m_b 也不能够影响外边main函数中的 x 和 y</li>
</ol>
<p>既然有了“传值”，你一定猜到了还会有“传引用”。Bingo! 你是对的。</p>
<p>在讨论“传引用”之前，我们先来看看另一个比较有用的东西。假设你有一大堆的局部变量需要被 lambda 使用，那么你的“捕获列表”将会写的很长，这肯定不是件愉快的事情。</p>
<p>好在 C++ 委员会的老头们也想到了，C++ 0x 中提供了一个省心的东西：如果捕获列表写成 [=]，表示 lambda 将捕获所有的局部变量，当然也是传值方式。这种方式姑且被称为“缺省捕获”：</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
</pre></td><td class="code"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">int</span> main<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
    vector<span style="color: #000080;">&lt;</span><span style="color: #0000ff;">int</span><span style="color: #000080;">&gt;</span> v<span style="color: #008080;">;</span>
    <span style="color: #0000ff;">for</span> <span style="color: #008000;">&#40;</span><span style="color: #0000ff;">int</span> i <span style="color: #000080;">=</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span> i <span style="color: #000080;">&lt;</span> <span style="color: #0000dd;">10</span><span style="color: #008080;">;</span> <span style="color: #000040;">++</span>i<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
        v.<span style="color: #007788;">push_back</span><span style="color: #008000;">&#40;</span>i<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #008000;">&#125;</span>
&nbsp;
    <span style="color: #0000ff;">int</span> x <span style="color: #000080;">=</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">int</span> y <span style="color: #000080;">=</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span>
&nbsp;
    <span style="color: #0000dd;">cout</span> <span style="color: #000080;">&lt;&lt;</span> <span style="color: #FF0000;">&quot;Input: &quot;</span><span style="color: #008080;">;</span>
    <span style="color: #0000dd;">cin</span> <span style="color: #000080;">&gt;&gt;</span> x <span style="color: #000080;">&gt;&gt;</span> y<span style="color: #008080;">;</span> <span style="color: #666666;">// EVIL!</span>
    v.<span style="color: #007788;">erase</span><span style="color: #008000;">&#40;</span>remove_if<span style="color: #008000;">&#40;</span>v.<span style="color: #007788;">begin</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>, v.<span style="color: #007788;">end</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>, <span style="color: #008000;">&#91;</span><span style="color: #000080;">=</span><span style="color: #008000;">&#93;</span><span style="color: #008000;">&#40;</span><span style="color: #0000ff;">int</span> n<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span> <span style="color: #0000ff;">return</span> x <span style="color: #000080;">&lt;</span> n <span style="color: #000040;">&amp;&amp;</span> n <span style="color: #000080;">&lt;</span> y<span style="color: #008080;">;</span> <span style="color: #008000;">&#125;</span><span style="color: #008000;">&#41;</span>, v.<span style="color: #007788;">end</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    for_each<span style="color: #008000;">&#40;</span>v.<span style="color: #007788;">begin</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>, v.<span style="color: #007788;">end</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>, <span style="color: #008000;">&#91;</span><span style="color: #008000;">&#93;</span><span style="color: #008000;">&#40;</span><span style="color: #0000ff;">int</span> n<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span> <span style="color: #0000dd;">cout</span> <span style="color: #000080;">&lt;&lt;</span> n <span style="color: #000080;">&lt;&lt;</span> <span style="color: #FF0000;">&quot; &quot;</span><span style="color: #008080;">;</span> <span style="color: #008000;">&#125;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000dd;">cout</span> <span style="color: #000080;">&lt;&lt;</span> endl<span style="color: #008080;">;</span>
&nbsp;
    <span style="color: #0000ff;">return</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

<p>当编译器在 lambda 的作用范围内看到局部变量 x、y 时，它会以传值的方式从 main 函数中将它们捕获。</p>
<p>下面我们来看如何突破前面提到的 3 点限制。</p>
<p>第 1 点，修改 lambda 表达式中的局部变量拷贝（e.g. m_a, m_b）。缺省情况下，lambda 的 operator() 是 const 修饰的，但是你可以使用 mutable 关键字改变这一点：</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
</pre></td><td class="code"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">int</span> main<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
    vector<span style="color: #000080;">&lt;</span><span style="color: #0000ff;">int</span><span style="color: #000080;">&gt;</span> v<span style="color: #008080;">;</span>
    <span style="color: #0000ff;">for</span> <span style="color: #008000;">&#40;</span><span style="color: #0000ff;">int</span> i <span style="color: #000080;">=</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span> i <span style="color: #000080;">&lt;</span> <span style="color: #0000dd;">10</span><span style="color: #008080;">;</span> <span style="color: #000040;">++</span>i<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
        v.<span style="color: #007788;">push_back</span><span style="color: #008000;">&#40;</span>i<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #008000;">&#125;</span>
&nbsp;
    <span style="color: #0000ff;">int</span> x <span style="color: #000080;">=</span> <span style="color: #0000dd;">1</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">int</span> y <span style="color: #000080;">=</span> <span style="color: #0000dd;">1</span><span style="color: #008080;">;</span>
&nbsp;
    for_each<span style="color: #008000;">&#40;</span>v.<span style="color: #007788;">begin</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>, v.<span style="color: #007788;">end</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>, <span style="color: #008000;">&#91;</span><span style="color: #000080;">=</span><span style="color: #008000;">&#93;</span><span style="color: #008000;">&#40;</span><span style="color: #0000ff;">int</span><span style="color: #000040;">&amp;</span> r<span style="color: #008000;">&#41;</span> mutable <span style="color: #008000;">&#123;</span>
        <span style="color: #0000ff;">const</span> <span style="color: #0000ff;">int</span> old <span style="color: #000080;">=</span> r<span style="color: #008080;">;</span>
        r <span style="color: #000040;">*</span><span style="color: #000080;">=</span> x <span style="color: #000040;">*</span> y<span style="color: #008080;">;</span>
        x <span style="color: #000080;">=</span> y<span style="color: #008080;">;</span>
        y <span style="color: #000080;">=</span> old<span style="color: #008080;">;</span>
    <span style="color: #008000;">&#125;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
&nbsp;
    for_each<span style="color: #008000;">&#40;</span>v.<span style="color: #007788;">begin</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>, v.<span style="color: #007788;">end</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>, <span style="color: #008000;">&#91;</span><span style="color: #008000;">&#93;</span><span style="color: #008000;">&#40;</span><span style="color: #0000ff;">int</span> n<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span> <span style="color: #0000dd;">cout</span> <span style="color: #000080;">&lt;&lt;</span> n <span style="color: #000080;">&lt;&lt;</span> <span style="color: #FF0000;">&quot; &quot;</span><span style="color: #008080;">;</span> <span style="color: #008000;">&#125;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000dd;">cout</span> <span style="color: #000080;">&lt;&lt;</span> endl<span style="color: #008080;">;</span>
    <span style="color: #0000dd;">cout</span> <span style="color: #000080;">&lt;&lt;</span> x <span style="color: #000080;">&lt;&lt;</span> <span style="color: #FF0000;">&quot;, &quot;</span> <span style="color: #000080;">&lt;&lt;</span> y <span style="color: #000080;">&lt;&lt;</span> endl<span style="color: #008080;">;</span>
&nbsp;
    <span style="color: #0000ff;">return</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

<p>运行结果如下：</p>

<div class="wp_syntax"><div class="code"><pre class="txt" style="font-family:monospace;">0 0 0 6 24 60 120 210 336 504
1, 1</pre></div></div>

<p>这里我们解决了第 1 个限制，但是却产生了一个新的限制：</p>
<ol start=4>
<li>lambda 中对捕获变量的修改并不会影响到 main 函数中的局部变量，因为 lambda 捕获局部变量使用的是传值方式</li>
</ol>
<p>下面该“传引用”的方式登场了，它能够有效地解决2，3，4三个限制。传引用的语法为： lambda-introducer [&amp;x, &amp;y]，这里的捕获列表应该理解为：X&amp; x, Y&amp; y，因为我们实际上是取的 x、y 的引用而不是地址。</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
</pre></td><td class="code"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">int</span> main<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
&nbsp;
    vector<span style="color: #000080;">&lt;</span><span style="color: #0000ff;">int</span><span style="color: #000080;">&gt;</span> v<span style="color: #008080;">;</span>
    <span style="color: #0000ff;">for</span> <span style="color: #008000;">&#40;</span><span style="color: #0000ff;">int</span> i <span style="color: #000080;">=</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span> i <span style="color: #000080;">&lt;</span> <span style="color: #0000dd;">10</span><span style="color: #008080;">;</span> <span style="color: #000040;">++</span>i<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
        v.<span style="color: #007788;">push_back</span><span style="color: #008000;">&#40;</span>i<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #008000;">&#125;</span>
&nbsp;
    <span style="color: #0000ff;">int</span> x <span style="color: #000080;">=</span> <span style="color: #0000dd;">1</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">int</span> y <span style="color: #000080;">=</span> <span style="color: #0000dd;">1</span><span style="color: #008080;">;</span>
&nbsp;
    for_each<span style="color: #008000;">&#40;</span>v.<span style="color: #007788;">begin</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>, v.<span style="color: #007788;">end</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>, <span style="color: #008000;">&#91;</span><span style="color: #000040;">&amp;</span>x, <span style="color: #000040;">&amp;</span>y<span style="color: #008000;">&#93;</span><span style="color: #008000;">&#40;</span><span style="color: #0000ff;">int</span><span style="color: #000040;">&amp;</span> r<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
        <span style="color: #0000ff;">const</span> <span style="color: #0000ff;">int</span> old <span style="color: #000080;">=</span> r<span style="color: #008080;">;</span>
        r <span style="color: #000040;">*</span><span style="color: #000080;">=</span> x <span style="color: #000040;">*</span> y<span style="color: #008080;">;</span>
        x <span style="color: #000080;">=</span> y<span style="color: #008080;">;</span>
        y <span style="color: #000080;">=</span> old<span style="color: #008080;">;</span>
    <span style="color: #008000;">&#125;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
&nbsp;
    for_each<span style="color: #008000;">&#40;</span>v.<span style="color: #007788;">begin</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>, v.<span style="color: #007788;">end</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>, <span style="color: #008000;">&#91;</span><span style="color: #008000;">&#93;</span><span style="color: #008000;">&#40;</span><span style="color: #0000ff;">int</span> n<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span> <span style="color: #0000dd;">cout</span> <span style="color: #000080;">&lt;&lt;</span> n <span style="color: #000080;">&lt;&lt;</span> <span style="color: #FF0000;">&quot; &quot;</span><span style="color: #008080;">;</span> <span style="color: #008000;">&#125;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000dd;">cout</span> <span style="color: #000080;">&lt;&lt;</span> endl<span style="color: #008080;">;</span>
    <span style="color: #0000dd;">cout</span> <span style="color: #000080;">&lt;&lt;</span> x <span style="color: #000080;">&lt;&lt;</span> <span style="color: #FF0000;">&quot;, &quot;</span> <span style="color: #000080;">&lt;&lt;</span> y <span style="color: #000080;">&lt;&lt;</span> endl<span style="color: #008080;">;</span>
&nbsp;
    <span style="color: #0000ff;">return</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

<p>运行结果如下：</p>

<div class="wp_syntax"><div class="code"><pre class="txt" style="font-family:monospace;">0 0 0 6 24 60 120 210 336 504
8, 9</pre></div></div>

<p>注意：当你使用 lambda 时，VC10 编译器会为 lambda 的定义部分自动禁用 C4512 警告。</p>
<p>当以传引用方式捕获局部变量时，lambda 的函数对象在自己内部以引用方式保存 main 函数中的局部变量。当然因为使用的是局部对象的引用，使用lambda表达式时一定要注意不能够超出局部变量的生命周期。</p>
<p>和上文提高的[=]类似，我们可以用[&#038;]来以“传引用”的方式捕获所有的局部变量。</p>
<p>到目前为止，局部变量的捕获方式要么是“值语义”要么是“引用语义”，那么可以混合这两种方式吗？可以！例如：[a, b, c, &amp;d, e, &amp;f, g]，其中变量 d 和 f 是按引用语义捕获，而 a、b、c、e 和 g 是按值语义捕获。</p>
<p>另外很有用的一点是：你可以指定一个缺省捕获，然后重载某些局部变量的捕获方式。下边例子中[=, &amp;sum, &amp;product] 告诉编译器用值语义方式捕获所有的局部变量，但是有两个例外 - sum和product是按引用语义来捕获。</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
</pre></td><td class="code"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">int</span> main<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
&nbsp;
    vector<span style="color: #000080;">&lt;</span><span style="color: #0000ff;">int</span><span style="color: #000080;">&gt;</span> v<span style="color: #008080;">;</span>
    <span style="color: #0000ff;">for</span> <span style="color: #008000;">&#40;</span><span style="color: #0000ff;">int</span> i <span style="color: #000080;">=</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span> i <span style="color: #000080;">&lt;</span> <span style="color: #0000dd;">10</span><span style="color: #008080;">;</span> <span style="color: #000040;">++</span>i<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
        v.<span style="color: #007788;">push_back</span><span style="color: #008000;">&#40;</span>i<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #008000;">&#125;</span>
&nbsp;
    <span style="color: #0000ff;">int</span> sum <span style="color: #000080;">=</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">int</span> product <span style="color: #000080;">=</span> <span style="color: #0000dd;">1</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">int</span> x <span style="color: #000080;">=</span> <span style="color: #0000dd;">1</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">int</span> y <span style="color: #000080;">=</span> <span style="color: #0000dd;">1</span><span style="color: #008080;">;</span>
&nbsp;
    for_each<span style="color: #008000;">&#40;</span>v.<span style="color: #007788;">begin</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>, v.<span style="color: #007788;">end</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>, <span style="color: #008000;">&#91;</span><span style="color: #000080;">=</span>, <span style="color: #000040;">&amp;</span>sum, <span style="color: #000040;">&amp;</span>product<span style="color: #008000;">&#93;</span><span style="color: #008000;">&#40;</span><span style="color: #0000ff;">int</span><span style="color: #000040;">&amp;</span> r<span style="color: #008000;">&#41;</span> mutable <span style="color: #008000;">&#123;</span>
        sum <span style="color: #000040;">+</span><span style="color: #000080;">=</span> r<span style="color: #008080;">;</span>
&nbsp;
        <span style="color: #0000ff;">if</span> <span style="color: #008000;">&#40;</span>r <span style="color: #000040;">!</span><span style="color: #000080;">=</span> <span style="color: #0000dd;">0</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
            product <span style="color: #000040;">*</span><span style="color: #000080;">=</span> r<span style="color: #008080;">;</span>
        <span style="color: #008000;">&#125;</span>
&nbsp;
        <span style="color: #0000ff;">const</span> <span style="color: #0000ff;">int</span> old <span style="color: #000080;">=</span> r<span style="color: #008080;">;</span>
        r <span style="color: #000040;">*</span><span style="color: #000080;">=</span> x <span style="color: #000040;">*</span> y<span style="color: #008080;">;</span>
        x <span style="color: #000080;">=</span> y<span style="color: #008080;">;</span>
        y <span style="color: #000080;">=</span> old<span style="color: #008080;">;</span>
    <span style="color: #008000;">&#125;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
&nbsp;
    for_each<span style="color: #008000;">&#40;</span>v.<span style="color: #007788;">begin</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>, v.<span style="color: #007788;">end</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>, <span style="color: #008000;">&#91;</span><span style="color: #008000;">&#93;</span><span style="color: #008000;">&#40;</span><span style="color: #0000ff;">int</span> n<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span> <span style="color: #0000dd;">cout</span> <span style="color: #000080;">&lt;&lt;</span> n <span style="color: #000080;">&lt;&lt;</span> <span style="color: #FF0000;">&quot; &quot;</span><span style="color: #008080;">;</span> <span style="color: #008000;">&#125;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000dd;">cout</span> <span style="color: #000080;">&lt;&lt;</span> endl<span style="color: #008080;">;</span>
    <span style="color: #0000dd;">cout</span> <span style="color: #000080;">&lt;&lt;</span> <span style="color: #FF0000;">&quot;sum: &quot;</span> <span style="color: #000080;">&lt;&lt;</span> sum <span style="color: #000080;">&lt;&lt;</span> <span style="color: #FF0000;">&quot;, product: &quot;</span> <span style="color: #000080;">&lt;&lt;</span> product <span style="color: #000080;">&lt;&lt;</span> endl<span style="color: #008080;">;</span>
    <span style="color: #0000dd;">cout</span> <span style="color: #000080;">&lt;&lt;</span> <span style="color: #FF0000;">&quot;x: &quot;</span> <span style="color: #000080;">&lt;&lt;</span> x <span style="color: #000080;">&lt;&lt;</span> <span style="color: #FF0000;">&quot;, y: &quot;</span> <span style="color: #000080;">&lt;&lt;</span> y <span style="color: #000080;">&lt;&lt;</span> endl<span style="color: #008080;">;</span>
&nbsp;
    <span style="color: #0000ff;">return</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

<p>运行结果如下：</p>

<div class="wp_syntax"><div class="code"><pre class="txt" style="font-family:monospace;">0 0 0 6 24 60 120 210 336 504
sum: 45, product: 362880
x: 1, y: 1</pre></div></div>

<p>再来看看下边的代码，在lambda中使用类成员变量：</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
</pre></td><td class="code"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">class</span> Kitty <span style="color: #008000;">&#123;</span>
&nbsp;
<span style="color: #0000ff;">public</span><span style="color: #008080;">:</span>
    <span style="color: #0000ff;">explicit</span> Kitty<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">int</span> toys<span style="color: #008000;">&#41;</span> <span style="color: #008080;">:</span> m_toys<span style="color: #008000;">&#40;</span>toys<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span><span style="color: #008000;">&#125;</span>
&nbsp;
    <span style="color: #0000ff;">void</span> meow<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">const</span> vector<span style="color: #000080;">&lt;</span><span style="color: #0000ff;">int</span><span style="color: #000080;">&gt;</span><span style="color: #000040;">&amp;</span> v<span style="color: #008000;">&#41;</span> <span style="color: #0000ff;">const</span> <span style="color: #008000;">&#123;</span>
        for_each<span style="color: #008000;">&#40;</span>v.<span style="color: #007788;">begin</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>, v.<span style="color: #007788;">end</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>, <span style="color: #008000;">&#91;</span>m_toys<span style="color: #008000;">&#93;</span><span style="color: #008000;">&#40;</span><span style="color: #0000ff;">int</span> n<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
            <span style="color: #0000dd;">cout</span> <span style="color: #000080;">&lt;&lt;</span> <span style="color: #FF0000;">&quot;If you gave me &quot;</span> <span style="color: #000080;">&lt;&lt;</span> n <span style="color: #000080;">&lt;&lt;</span> <span style="color: #FF0000;">&quot; toys, I would have &quot;</span> <span style="color: #000080;">&lt;&lt;</span> n <span style="color: #000040;">+</span> m_toys <span style="color: #000080;">&lt;&lt;</span> <span style="color: #FF0000;">&quot; toys total.&quot;</span> <span style="color: #000080;">&lt;&lt;</span> endl<span style="color: #008080;">;</span>
        <span style="color: #008000;">&#125;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #008000;">&#125;</span>
&nbsp;
<span style="color: #0000ff;">private</span><span style="color: #008080;">:</span>
    <span style="color: #0000ff;">int</span> m_toys<span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span><span style="color: #008080;">;</span>
&nbsp;
<span style="color: #0000ff;">int</span> main<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
    vector<span style="color: #000080;">&lt;</span><span style="color: #0000ff;">int</span><span style="color: #000080;">&gt;</span> v<span style="color: #008080;">;</span>
    <span style="color: #0000ff;">for</span> <span style="color: #008000;">&#40;</span><span style="color: #0000ff;">int</span> i <span style="color: #000080;">=</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span> i <span style="color: #000080;">&lt;</span> <span style="color: #0000dd;">3</span><span style="color: #008080;">;</span> <span style="color: #000040;">++</span>i<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
        v.<span style="color: #007788;">push_back</span><span style="color: #008000;">&#40;</span>i<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #008000;">&#125;</span>
&nbsp;
    Kitty k<span style="color: #008000;">&#40;</span><span style="color: #0000dd;">5</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    k.<span style="color: #007788;">meow</span><span style="color: #008000;">&#40;</span>v<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
&nbsp;
    <span style="color: #0000ff;">return</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

<p>不幸的是，编译这段代码将产生这样的错误：</p>

<div class="wp_syntax"><div class="code"><pre class="txt" style="font-family:monospace;">error C3480: 'Kitty::m_toys': a lambda capture variable must be from an enclosing function scope</pre></div></div>

<p>为什么呢？lambda表达式能够让你不活局部变量，但是类的数据成员并不是局部变量。解决方案呢？别着急。lambda 为捕获类的数据成员大开方便之门，你可以捕获this指针。</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
</pre></td><td class="code"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">class</span> Kitty <span style="color: #008000;">&#123;</span>
<span style="color: #0000ff;">public</span><span style="color: #008080;">:</span>
    <span style="color: #0000ff;">explicit</span> Kitty<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">int</span> toys<span style="color: #008000;">&#41;</span> <span style="color: #008080;">:</span> m_toys<span style="color: #008000;">&#40;</span>toys<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span><span style="color: #008000;">&#125;</span>
    <span style="color: #0000ff;">void</span> meow<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">const</span> vector<span style="color: #000080;">&lt;</span><span style="color: #0000ff;">int</span><span style="color: #000080;">&gt;</span><span style="color: #000040;">&amp;</span> v<span style="color: #008000;">&#41;</span> <span style="color: #0000ff;">const</span> <span style="color: #008000;">&#123;</span>
        for_each<span style="color: #008000;">&#40;</span>v.<span style="color: #007788;">begin</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>, v.<span style="color: #007788;">end</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>, <span style="color: #008000;">&#91;</span><span style="color: #0000dd;">this</span><span style="color: #008000;">&#93;</span><span style="color: #008000;">&#40;</span><span style="color: #0000ff;">int</span> n<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
            <span style="color: #0000dd;">cout</span> <span style="color: #000080;">&lt;&lt;</span> <span style="color: #FF0000;">&quot;If you gave me &quot;</span> <span style="color: #000080;">&lt;&lt;</span> n <span style="color: #000080;">&lt;&lt;</span> <span style="color: #FF0000;">&quot; toys, I would have &quot;</span> <span style="color: #000080;">&lt;&lt;</span> n <span style="color: #000040;">+</span> m_toys <span style="color: #000080;">&lt;&lt;</span> <span style="color: #FF0000;">&quot; toys total.&quot;</span> <span style="color: #000080;">&lt;&lt;</span> endl<span style="color: #008080;">;</span>
        <span style="color: #008000;">&#125;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #008000;">&#125;</span>
&nbsp;
<span style="color: #0000ff;">private</span><span style="color: #008080;">:</span>
    <span style="color: #0000ff;">int</span> m_toys<span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span><span style="color: #008080;">;</span>
&nbsp;
<span style="color: #0000ff;">int</span> main<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
    vector<span style="color: #000080;">&lt;</span><span style="color: #0000ff;">int</span><span style="color: #000080;">&gt;</span> v<span style="color: #008080;">;</span>
    <span style="color: #0000ff;">for</span> <span style="color: #008000;">&#40;</span><span style="color: #0000ff;">int</span> i <span style="color: #000080;">=</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span> i <span style="color: #000080;">&lt;</span> <span style="color: #0000dd;">3</span><span style="color: #008080;">;</span> <span style="color: #000040;">++</span>i<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
        v.<span style="color: #007788;">push_back</span><span style="color: #008000;">&#40;</span>i<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #008000;">&#125;</span>
&nbsp;
    Kitty k<span style="color: #008000;">&#40;</span><span style="color: #0000dd;">5</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    k.<span style="color: #007788;">meow</span><span style="color: #008000;">&#40;</span>v<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
&nbsp;
    <span style="color: #0000ff;">return</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

<p>运行结果如下：</p>

<div class="wp_syntax"><div class="code"><pre class="txt" style="font-family:monospace;">If you gave me 0 toys, I would have 5 toys total.
If you gave me 1 toys, I would have 6 toys total.
If you gave me 2 toys, I would have 7 toys total.</pre></div></div>

<p>当 lambda 表达式捕获“this”时，编译器看到 m_toys 后会在 this 所指向对象的范围内进行名字查找，m_toys 被隐式地推演为 this-&gt;m_toys。当然你也可以让编译器省省力气，显式地在捕获列表中使用 this-&gt;m_toys。另外，lambda 比较智能，你也可以隐式地捕获 this 指针，如下所示：</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
</pre></td><td class="code"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">class</span> Kitty <span style="color: #008000;">&#123;</span>
&nbsp;
<span style="color: #0000ff;">public</span><span style="color: #008080;">:</span>
    <span style="color: #0000ff;">explicit</span> Kitty<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">int</span> toys<span style="color: #008000;">&#41;</span> <span style="color: #008080;">:</span> m_toys<span style="color: #008000;">&#40;</span>toys<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span> <span style="color: #008000;">&#125;</span>
    <span style="color: #0000ff;">void</span> meow<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">const</span> vector<span style="color: #000080;">&lt;</span><span style="color: #0000ff;">int</span><span style="color: #000080;">&gt;</span><span style="color: #000040;">&amp;</span> v<span style="color: #008000;">&#41;</span> <span style="color: #0000ff;">const</span> <span style="color: #008000;">&#123;</span>
        for_each<span style="color: #008000;">&#40;</span>v.<span style="color: #007788;">begin</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>, v.<span style="color: #007788;">end</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>, <span style="color: #008000;">&#91;</span><span style="color: #000080;">=</span><span style="color: #008000;">&#93;</span><span style="color: #008000;">&#40;</span><span style="color: #0000ff;">int</span> n<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
            <span style="color: #0000dd;">cout</span> <span style="color: #000080;">&lt;&lt;</span> <span style="color: #FF0000;">&quot;If you gave me &quot;</span> <span style="color: #000080;">&lt;&lt;</span> n <span style="color: #000080;">&lt;&lt;</span> <span style="color: #FF0000;">&quot; toys, I would have &quot;</span> <span style="color: #000080;">&lt;&lt;</span> n <span style="color: #000040;">+</span> m_toys <span style="color: #000080;">&lt;&lt;</span> <span style="color: #FF0000;">&quot; toys total.&quot;</span> <span style="color: #000080;">&lt;&lt;</span> endl<span style="color: #008080;">;</span>
        <span style="color: #008000;">&#125;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #008000;">&#125;</span>
&nbsp;
<span style="color: #0000ff;">private</span><span style="color: #008080;">:</span>
    <span style="color: #0000ff;">int</span> m_toys<span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span><span style="color: #008080;">;</span>
&nbsp;
<span style="color: #0000ff;">int</span> main<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
    vector<span style="color: #000080;">&lt;</span><span style="color: #0000ff;">int</span><span style="color: #000080;">&gt;</span> v<span style="color: #008080;">;</span>
    <span style="color: #0000ff;">for</span> <span style="color: #008000;">&#40;</span><span style="color: #0000ff;">int</span> i <span style="color: #000080;">=</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span> i <span style="color: #000080;">&lt;</span> <span style="color: #0000dd;">3</span><span style="color: #008080;">;</span> <span style="color: #000040;">++</span>i<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
        v.<span style="color: #007788;">push_back</span><span style="color: #008000;">&#40;</span>i<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #008000;">&#125;</span>
&nbsp;
    Kitty k<span style="color: #008000;">&#40;</span><span style="color: #0000dd;">5</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    k.<span style="color: #007788;">meow</span><span style="color: #008000;">&#40;</span>v<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

<p>运行结果如下：</p>

<div class="wp_syntax"><div class="code"><pre class="txt" style="font-family:monospace;">If you gave me 0 toys, I would have 5 toys total.
If you gave me 1 toys, I would have 6 toys total.
If you gave me 2 toys, I would have 7 toys total.</pre></div></div>

<p>注意你也可以在上面代码中用 [&amp;]，但是结果是一样的——this 指针永远是按值语义被传递(捕获)的。你也不能够使用 [&amp;this]，呵呵。</p>
<p>如果你的 lambda 表达式是没有参数的，那么 lambda 表达式的导入符后边的括号()也可以省掉。例如：</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
</pre></td><td class="code"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">int</span> main<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
    vector<span style="color: #000080;">&lt;</span><span style="color: #0000ff;">int</span><span style="color: #000080;">&gt;</span> v<span style="color: #008080;">;</span>
    <span style="color: #0000ff;">int</span> i <span style="color: #000080;">=</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span>
    generate_n<span style="color: #008000;">&#40;</span>back_inserter<span style="color: #008000;">&#40;</span>v<span style="color: #008000;">&#41;</span>, <span style="color: #0000dd;">10</span>, <span style="color: #008000;">&#91;</span><span style="color: #000040;">&amp;</span><span style="color: #008000;">&#93;</span> <span style="color: #008000;">&#123;</span> <span style="color: #0000ff;">return</span> i<span style="color: #000040;">++</span><span style="color: #008080;">;</span> <span style="color: #008000;">&#125;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    for_each<span style="color: #008000;">&#40;</span>v.<span style="color: #007788;">begin</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>, v.<span style="color: #007788;">end</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>, <span style="color: #008000;">&#91;</span><span style="color: #008000;">&#93;</span><span style="color: #008000;">&#40;</span><span style="color: #0000ff;">int</span> n<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span> <span style="color: #0000dd;">cout</span> <span style="color: #000080;">&lt;&lt;</span> n <span style="color: #000080;">&lt;&lt;</span> <span style="color: #FF0000;">&quot; &quot;</span><span style="color: #008080;">;</span> <span style="color: #008000;">&#125;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000dd;">cout</span> <span style="color: #000080;">&lt;&lt;</span> endl<span style="color: #008080;">;</span>
    <span style="color: #0000dd;">cout</span> <span style="color: #000080;">&lt;&lt;</span> <span style="color: #FF0000;">&quot;i: &quot;</span> <span style="color: #000080;">&lt;&lt;</span> i <span style="color: #000080;">&lt;&lt;</span> endl<span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

<p>上边是 [&amp;]() { return i++; }的简写形式，个人认为省掉括号并不是什么好的 coding style。如果你需要用到mutable或者指定lambda的返回类型，空的括号就不能够省略了。</p>
<p>最后，既然 lambda 表达式生成是普通的函数对象，所以函数对象支持的用法 lambda 都支持。例如和 tr1 的 function 一起使用，看看下边的代码，是不是很酷？</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
</pre></td><td class="code"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">using</span> <span style="color: #0000ff;">namespace</span> std<span style="color: #008080;">;</span>
<span style="color: #0000ff;">using</span> <span style="color: #0000ff;">namespace</span> std<span style="color: #008080;">::</span><span style="color: #007788;">tr1</span><span style="color: #008080;">;</span>
&nbsp;
<span style="color: #0000ff;">void</span> meow<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">const</span> vector<span style="color: #000080;">&lt;</span><span style="color: #0000ff;">int</span><span style="color: #000080;">&gt;</span><span style="color: #000040;">&amp;</span> v, <span style="color: #0000ff;">const</span> function<span style="color: #000080;">&lt;</span><span style="color: #0000ff;">void</span> <span style="color: #008000;">&#40;</span><span style="color: #0000ff;">int</span><span style="color: #008000;">&#41;</span><span style="color: #000080;">&gt;</span><span style="color: #000040;">&amp;</span> f<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
    for_each<span style="color: #008000;">&#40;</span>v.<span style="color: #007788;">begin</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>, v.<span style="color: #007788;">end</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>, f<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000dd;">cout</span> <span style="color: #000080;">&lt;&lt;</span> endl<span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span>
&nbsp;
<span style="color: #0000ff;">int</span> main<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
    vector<span style="color: #000080;">&lt;</span><span style="color: #0000ff;">int</span><span style="color: #000080;">&gt;</span> v<span style="color: #008080;">;</span>
    <span style="color: #0000ff;">for</span> <span style="color: #008000;">&#40;</span><span style="color: #0000ff;">int</span> i <span style="color: #000080;">=</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span> i <span style="color: #000080;">&lt;</span> <span style="color: #0000dd;">10</span><span style="color: #008080;">;</span> <span style="color: #000040;">++</span>i<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
        v.<span style="color: #007788;">push_back</span><span style="color: #008000;">&#40;</span>i<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #008000;">&#125;</span>
&nbsp;
    meow<span style="color: #008000;">&#40;</span>v, <span style="color: #008000;">&#91;</span><span style="color: #008000;">&#93;</span><span style="color: #008000;">&#40;</span><span style="color: #0000ff;">int</span> n<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span> <span style="color: #0000dd;">cout</span> <span style="color: #000080;">&lt;&lt;</span> n <span style="color: #000080;">&lt;&lt;</span> <span style="color: #FF0000;">&quot; &quot;</span><span style="color: #008080;">;</span> <span style="color: #008000;">&#125;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    meow<span style="color: #008000;">&#40;</span>v, <span style="color: #008000;">&#91;</span><span style="color: #008000;">&#93;</span><span style="color: #008000;">&#40;</span><span style="color: #0000ff;">int</span> n<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span> <span style="color: #0000dd;">cout</span> <span style="color: #000080;">&lt;&lt;</span> n <span style="color: #000040;">*</span> n <span style="color: #000080;">&lt;&lt;</span> <span style="color: #FF0000;">&quot; &quot;</span><span style="color: #008080;">;</span> <span style="color: #008000;">&#125;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
&nbsp;
    function<span style="color: #000080;">&lt;</span><span style="color: #0000ff;">void</span> <span style="color: #008000;">&#40;</span><span style="color: #0000ff;">int</span><span style="color: #008000;">&#41;</span><span style="color: #000080;">&gt;</span> g <span style="color: #000080;">=</span> <span style="color: #008000;">&#91;</span><span style="color: #008000;">&#93;</span><span style="color: #008000;">&#40;</span><span style="color: #0000ff;">int</span> n<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span> <span style="color: #0000dd;">cout</span> <span style="color: #000080;">&lt;&lt;</span> n <span style="color: #000040;">*</span> n <span style="color: #000040;">*</span> n <span style="color: #000080;">&lt;&lt;</span> <span style="color: #FF0000;">&quot; &quot;</span><span style="color: #008080;">;</span> <span style="color: #008000;">&#125;</span><span style="color: #008080;">;</span>
    meow<span style="color: #008000;">&#40;</span>v, g<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
&nbsp;
    <span style="color: #0000ff;">return</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

<p>运行结果：</p>

<div class="wp_syntax"><div class="code"><pre class="txt" style="font-family:monospace;">0 1 2 3 4 5 6 7 8 9
0 1 4 9 16 25 36 49 64 81
0 1 8 27 64 125 216 343 512 729</pre></div></div>

<h3>auto 关键字</h3>
<p>auto 这个关键字来自 C++ 98 标准。在 C++ 98 中它没有什么作用，C++ 0x 中“借用”它来作为自动类型推演(automatic type deduction)。当 auto 出现在声明中时，它表示“请用初始化我的表达式类型作为我的类型”，例如下面代码：</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
</pre></td><td class="code"><pre class="cpp" style="font-family:monospace;"><span style="color: #339900;">#include &lt;iostream&gt;</span>
<span style="color: #339900;">#include &lt;map&gt;</span>
<span style="color: #339900;">#include &lt;ostream&gt;</span>
<span style="color: #339900;">#include &lt;regex&gt;</span>
<span style="color: #339900;">#include &lt;string&gt;</span>
&nbsp;
<span style="color: #0000ff;">using</span> <span style="color: #0000ff;">namespace</span> std<span style="color: #008080;">;</span>
<span style="color: #0000ff;">using</span> <span style="color: #0000ff;">namespace</span> std<span style="color: #008080;">::</span><span style="color: #007788;">tr1</span><span style="color: #008080;">;</span>
&nbsp;
<span style="color: #0000ff;">int</span> main<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
    map<span style="color: #000080;">&lt;</span>string, string<span style="color: #000080;">&gt;</span> m<span style="color: #008080;">;</span>
&nbsp;
    <span style="color: #0000ff;">const</span> regex r<span style="color: #008000;">&#40;</span><span style="color: #FF0000;">&quot;(\\w+) (\\w+)&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
&nbsp;
    <span style="color: #0000ff;">for</span> <span style="color: #008000;">&#40;</span>string s<span style="color: #008080;">;</span> getline<span style="color: #008000;">&#40;</span><span style="color: #0000dd;">cin</span>, s<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span> <span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
        smatch results<span style="color: #008080;">;</span>
&nbsp;
        <span style="color: #0000ff;">if</span> <span style="color: #008000;">&#40;</span>regex_match<span style="color: #008000;">&#40;</span>s, results, r<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
            m<span style="color: #008000;">&#91;</span>results<span style="color: #008000;">&#91;</span><span style="color: #0000dd;">1</span><span style="color: #008000;">&#93;</span><span style="color: #008000;">&#93;</span> <span style="color: #000080;">=</span> results<span style="color: #008000;">&#91;</span><span style="color: #0000dd;">2</span><span style="color: #008000;">&#93;</span><span style="color: #008080;">;</span>
        <span style="color: #008000;">&#125;</span>
    <span style="color: #008000;">&#125;</span>
&nbsp;
    <span style="color: #0000ff;">for</span> <span style="color: #008000;">&#40;</span><span style="color: #0000ff;">auto</span> i <span style="color: #000080;">=</span> m.<span style="color: #007788;">begin</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span> i <span style="color: #000040;">!</span><span style="color: #000080;">=</span> m.<span style="color: #007788;">end</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span> <span style="color: #000040;">++</span>i<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
        <span style="color: #0000dd;">cout</span> <span style="color: #000080;">&lt;&lt;</span> i<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>second <span style="color: #000080;">&lt;&lt;</span> <span style="color: #FF0000;">&quot; are &quot;</span> <span style="color: #000080;">&lt;&lt;</span> i<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>first <span style="color: #000080;">&lt;&lt;</span> endl<span style="color: #008080;">;</span>
    <span style="color: #008000;">&#125;</span>
&nbsp;
    <span style="color: #0000ff;">return</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

<p>运行结果如下：</p>

<div class="wp_syntax"><div class="code"><pre class="txt" style="font-family:monospace;">cute kittens
ugly puppies
evil goblins
^Z
kittens are cute
goblins are evil
puppies are ugly</pre></div></div>

<p>上面例子中i的类型在编译时推演为 map<string, string>::iterator, 有了 auto 关键字你再也不用写又长又烦的代码了。（注意 m.begin() 返回类型是 iterator, 而不是 const_iterator, 因为这里的 m 并不是 const。C++0x 中的 cbegin() 能够解决这个问题，它返回 non-const 容器的 const 迭代器。）</p>
<p><strong>Lambda 表达式和 auto 关键字的配合</strong></p>
<p>上文中提到了用 tr1::functions 来存储 lambda 表达式，但是不建议那样做除非不得已，因为 tr1::functions 的开销问题。如果你需要复用 lambda 表达式或者像给它命名，那么 auto 是更好的选择。</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
</pre></td><td class="code"><pre class="cpp" style="font-family:monospace;"><span style="color: #339900;">#include &lt;algorithm&gt;</span>
<span style="color: #339900;">#include &lt;iostream&gt;</span>
<span style="color: #339900;">#include &lt;ostream&gt;</span>
<span style="color: #339900;">#include &lt;vector&gt;</span>
&nbsp;
<span style="color: #0000ff;">using</span> <span style="color: #0000ff;">namespace</span> std<span style="color: #008080;">;</span>
&nbsp;
<span style="color: #0000ff;">template</span> <span style="color: #000080;">&lt;</span><span style="color: #0000ff;">typename</span> T, <span style="color: #0000ff;">typename</span> Predicate<span style="color: #000080;">&gt;</span> <span style="color: #0000ff;">void</span> keep_if<span style="color: #008000;">&#40;</span>vector<span style="color: #000080;">&lt;</span>T<span style="color: #000080;">&gt;</span><span style="color: #000040;">&amp;</span> v, Predicate pred<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
    <span style="color: #0000ff;">auto</span> notpred <span style="color: #000080;">=</span> <span style="color: #008000;">&#91;</span><span style="color: #000040;">&amp;</span><span style="color: #008000;">&#93;</span><span style="color: #008000;">&#40;</span><span style="color: #0000ff;">const</span> T<span style="color: #000040;">&amp;</span> t<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
        <span style="color: #0000ff;">return</span> <span style="color: #000040;">!</span>pred<span style="color: #008000;">&#40;</span>t<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #008000;">&#125;</span><span style="color: #008080;">;</span>
&nbsp;
    v.<span style="color: #007788;">erase</span><span style="color: #008000;">&#40;</span>remove_if<span style="color: #008000;">&#40;</span>v.<span style="color: #007788;">begin</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>, v.<span style="color: #007788;">end</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>, notpred<span style="color: #008000;">&#41;</span>, v.<span style="color: #007788;">end</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span>
&nbsp;
<span style="color: #0000ff;">template</span> <span style="color: #000080;">&lt;</span><span style="color: #0000ff;">typename</span> Container<span style="color: #000080;">&gt;</span> <span style="color: #0000ff;">void</span> print<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">const</span> Container<span style="color: #000040;">&amp;</span> c<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
    for_each<span style="color: #008000;">&#40;</span>c.<span style="color: #007788;">begin</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>, c.<span style="color: #007788;">end</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>, <span style="color: #008000;">&#91;</span><span style="color: #008000;">&#93;</span><span style="color: #008000;">&#40;</span><span style="color: #0000ff;">const</span> <span style="color: #0000ff;">typename</span> Container<span style="color: #008080;">::</span><span style="color: #007788;">value_type</span><span style="color: #000040;">&amp;</span> e<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span> <span style="color: #0000dd;">cout</span> <span style="color: #000080;">&lt;&lt;</span> e <span style="color: #000080;">&lt;&lt;</span> <span style="color: #FF0000;">&quot; &quot;</span><span style="color: #008080;">;</span> <span style="color: #008000;">&#125;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000dd;">cout</span> <span style="color: #000080;">&lt;&lt;</span> endl<span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span>
&nbsp;
<span style="color: #0000ff;">int</span> main<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
    vector<span style="color: #000080;">&lt;</span><span style="color: #0000ff;">int</span><span style="color: #000080;">&gt;</span> a<span style="color: #008080;">;</span>
&nbsp;
    <span style="color: #0000ff;">for</span> <span style="color: #008000;">&#40;</span><span style="color: #0000ff;">int</span> i <span style="color: #000080;">=</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span> i <span style="color: #000080;">&lt;</span> <span style="color: #0000dd;">100</span><span style="color: #008080;">;</span> <span style="color: #000040;">++</span>i<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
        a.<span style="color: #007788;">push_back</span><span style="color: #008000;">&#40;</span>i<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #008000;">&#125;</span>
&nbsp;
    vector<span style="color: #000080;">&lt;</span><span style="color: #0000ff;">int</span><span style="color: #000080;">&gt;</span> b<span style="color: #008080;">;</span>
&nbsp;
    <span style="color: #0000ff;">for</span> <span style="color: #008000;">&#40;</span><span style="color: #0000ff;">int</span> i <span style="color: #000080;">=</span> <span style="color: #0000dd;">100</span><span style="color: #008080;">;</span> i <span style="color: #000080;">&lt;</span> <span style="color: #0000dd;">200</span><span style="color: #008080;">;</span> <span style="color: #000040;">++</span>i<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
        b.<span style="color: #007788;">push_back</span><span style="color: #008000;">&#40;</span>i<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #008000;">&#125;</span>
&nbsp;
    <span style="color: #0000ff;">auto</span> prime <span style="color: #000080;">=</span> <span style="color: #008000;">&#91;</span><span style="color: #008000;">&#93;</span><span style="color: #008000;">&#40;</span><span style="color: #0000ff;">const</span> <span style="color: #0000ff;">int</span> n<span style="color: #008000;">&#41;</span> <span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span> <span style="color: #0000ff;">bool</span> <span style="color: #008000;">&#123;</span>
        <span style="color: #0000ff;">if</span> <span style="color: #008000;">&#40;</span>n <span style="color: #000080;">&lt;</span> <span style="color: #0000dd;">2</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
            <span style="color: #0000ff;">return</span> <span style="color: #0000ff;">false</span><span style="color: #008080;">;</span>
        <span style="color: #008000;">&#125;</span>
&nbsp;
        <span style="color: #0000ff;">for</span> <span style="color: #008000;">&#40;</span><span style="color: #0000ff;">int</span> i <span style="color: #000080;">=</span> <span style="color: #0000dd;">2</span><span style="color: #008080;">;</span> i <span style="color: #000080;">&lt;=</span> n <span style="color: #000040;">/</span> i<span style="color: #008080;">;</span> <span style="color: #000040;">++</span>i<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
            <span style="color: #0000ff;">if</span> <span style="color: #008000;">&#40;</span>n <span style="color: #000040;">%</span> i <span style="color: #000080;">==</span> <span style="color: #0000dd;">0</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
                <span style="color: #0000ff;">return</span> <span style="color: #0000ff;">false</span><span style="color: #008080;">;</span>
            <span style="color: #008000;">&#125;</span>
        <span style="color: #008000;">&#125;</span>
        <span style="color: #0000ff;">return</span> <span style="color: #0000ff;">true</span><span style="color: #008080;">;</span>
    <span style="color: #008000;">&#125;</span><span style="color: #008080;">;</span>
&nbsp;
    keep_if<span style="color: #008000;">&#40;</span>a, prime<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    keep_if<span style="color: #008000;">&#40;</span>b, prime<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    print<span style="color: #008000;">&#40;</span>a<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    print<span style="color: #008000;">&#40;</span>b<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
&nbsp;
    <span style="color: #0000ff;">return</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

<p>运行结果如下：</p>

<div class="wp_syntax"><div class="code"><pre class="txt" style="font-family:monospace;">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
101 103 107 109 113 127 131 137 139 149 151 157 163 167 173 179 181 191 193 197 199</pre></div></div>

<p>上面代码中 notpred 是一个 lambda 表达式的否定式。这个例子中我们不能够使用 C++ 98 的 not1()，因为 not1 要求你的谓词是从 unary_function 派生的，但是 lambda 并不要求这点，所以很多情况下使用 lambda 更灵活。</p>
<h3>静态断言 static_assert</h3>
<p>断言（assertion）是提高代码质量的有效武器。C++标准库中的 assert、MFC 中的 ASSERT /VERIFY 宏都是断言的例子，它们的共同点是在运行时对程序状态进行判断，例如检查函数的参数有效性、检查类的不变式等。而 C++ 0x 中的静态断言呢，和运行时的断言不一样，它是编译时执行检查的。看下面的例子：</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
</pre></td><td class="code"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">template</span> <span style="color: #000080;">&lt;</span><span style="color: #0000ff;">int</span> N<span style="color: #000080;">&gt;</span> <span style="color: #0000ff;">struct</span> Kitten <span style="color: #008000;">&#123;</span>
static_assert<span style="color: #008000;">&#40;</span>N <span style="color: #000080;">&lt;</span> <span style="color: #0000dd;">2</span>, <span style="color: #FF0000;">&quot;Kitten&lt;N&gt; requires N &lt; 2.&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span><span style="color: #008080;">;</span>
&nbsp;
<span style="color: #0000ff;">int</span> main<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
    Kitten<span style="color: #000080;">&lt;</span><span style="color: #0000dd;">1</span><span style="color: #000080;">&gt;</span> peppermint<span style="color: #008080;">;</span>
    Kitten<span style="color: #000080;">&lt;</span><span style="color: #0000dd;">3</span><span style="color: #000080;">&gt;</span> jazz<span style="color: #008080;">;</span>
&nbsp;
    <span style="color: #0000ff;">return</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

<p>编译结果如下：</p>

<div class="wp_syntax"><div class="code"><pre class="txt" style="font-family:monospace;">staticfluffykitten.cpp(2) : error C2338: Kitten&lt;N&gt; requires N &lt; 2.
        staticfluffykitten.cpp(8) : see reference to class template instantiation 'Kitten&lt;N&gt;' being compiled
        with
        [
            N=3
        ]</pre></div></div>

<p>上面例子中用 static_assert 对模板参数 N 进行了检查，如果断言失败编译器将使用用户自定义的错误消息。</p>


<p>Related posts:<ul><li><a href='http://wutiam.net/2009/06/uninstalling-visual-studio-2008-may-fail-to-load-setup-components/' rel='bookmark' title='Permanent Link: Visual Studio 2008 无法进入修复/卸载界面的解决办法'>Visual Studio 2008 无法进入修复/卸载界面的解决办法</a></li>
<li><a href='http://wutiam.net/2009/05/ctreectrl-traversal/' rel='bookmark' title='Permanent Link: 遍历 CTreeCtrl'>遍历 CTreeCtrl</a></li>
<li><a href='http://wutiam.net/2009/04/some-vs2005-and-vs2008-wizards-pop-up-script-error/' rel='bookmark' title='Permanent Link: IE8 引发 VS 2005/2008 向导出错的解决方案'>IE8 引发 VS 2005/2008 向导出错的解决方案</a></li>
</ul></p>]]></content:encoded>
			<wfw:commentRss>http://wutiam.net/2010/06/lambdas-auto-and-static-assert-c-0x-features-in-vc10/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>乱用 STL 是地狱</title>
		<link>http://wutiam.net/2010/04/stl-on-the-wrong-way-may-lead-to-hell/</link>
		<comments>http://wutiam.net/2010/04/stl-on-the-wrong-way-may-lead-to-hell/#comments</comments>
		<pubDate>Mon, 19 Apr 2010 05:43:21 +0000</pubDate>
		<dc:creator>islet8</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[c++]]></category>
		<category><![CDATA[stl]]></category>

		<guid isPermaLink="false">http://wutiam.net/?p=128</guid>
		<description><![CDATA[根据《Effective STL》条款21中的例子，建立一个比较类型为 less_equal 的 set 容器：

    set&#60; int, less_equal&#60;int&#62; &#62; s;

然后连续插入两个10：

    s.insert&#40;10&#41;; // 10a
    s.insert&#40;10&#41;; // 10b

会得到什么？
在debug下，可能会给出一个assert报比较符号不合法，第二次插入失败，但在release下，这个动作很可能是未定义的，而通常的结果是，set中存在了两个键值同为10的项，也就是说，set被悄声无息地变成了multiset！太可怕了！
所以，为正确的容器挑选正确的比较函数，很重要。用好 STL 其实并不容易，用错了不仅执行效率狂低，而且还可能出现这些难以想象的意外……


Related posts:避免在 C++ 类结构中出现私有虚成员函数
让 C++ 的 new 操作失败时返回空指针
严重避免在构造/析构过程中调用虚函数



Related posts:<ul><li><a href='http://wutiam.net/2010/07/avoid-private-virtual-member-function-in-cpp-class/' rel='bookmark' title='Permanent Link: 避免在 C++ 类结构中出现私有虚成员函数'>避免在 C++ 类结构中出现私有虚成员函数</a></li>
<li><a href='http://wutiam.net/2010/02/let-cpp-new-operator-return-null-when-failed/' rel='bookmark' title='Permanent Link: 让 C++ 的 new 操作失败时返回空指针'>让 C++ 的 new 操作失败时返回空指针</a></li>
<li><a href='http://wutiam.net/2010/01/prevent-invoking-virtual-functions-in-constructor-and-destructor/' rel='bookmark' title='Permanent Link: 严重避免在构造/析构过程中调用虚函数'>严重避免在构造/析构过程中调用虚函数</a></li>
</ul>]]></description>
			<content:encoded><![CDATA[<p>根据《Effective STL》条款21中的例子，建立一个比较类型为 less_equal 的 set 容器：</p>

<div class="wp_syntax"><div class="code"><pre class="cpp" style="font-family:monospace;">    set<span style="color: #000080;">&lt;</span> <span style="color: #0000ff;">int</span>, less_equal<span style="color: #000080;">&lt;</span><span style="color: #0000ff;">int</span><span style="color: #000080;">&gt;</span> <span style="color: #000080;">&gt;</span> s<span style="color: #008080;">;</span></pre></div></div>

<p>然后连续插入两个10：</p>

<div class="wp_syntax"><div class="code"><pre class="cpp" style="font-family:monospace;">    s.<span style="color: #007788;">insert</span><span style="color: #008000;">&#40;</span><span style="color: #0000dd;">10</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span> <span style="color: #666666;">// 10a</span>
    s.<span style="color: #007788;">insert</span><span style="color: #008000;">&#40;</span><span style="color: #0000dd;">10</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span> <span style="color: #666666;">// 10b</span></pre></div></div>

<p>会得到什么？</p>
<p>在debug下，可能会给出一个assert报比较符号不合法，第二次插入失败，但在release下，这个动作很可能是未定义的，而通常的结果是，set中存在了两个键值同为10的项，也就是说，set被悄声无息地变成了multiset！太可怕了！</p>
<p>所以，为正确的容器挑选正确的比较函数，很重要。用好 STL 其实并不容易，用错了不仅执行效率狂低，而且还可能出现这些难以想象的意外……</p>


<p>Related posts:<ul><li><a href='http://wutiam.net/2010/07/avoid-private-virtual-member-function-in-cpp-class/' rel='bookmark' title='Permanent Link: 避免在 C++ 类结构中出现私有虚成员函数'>避免在 C++ 类结构中出现私有虚成员函数</a></li>
<li><a href='http://wutiam.net/2010/02/let-cpp-new-operator-return-null-when-failed/' rel='bookmark' title='Permanent Link: 让 C++ 的 new 操作失败时返回空指针'>让 C++ 的 new 操作失败时返回空指针</a></li>
<li><a href='http://wutiam.net/2010/01/prevent-invoking-virtual-functions-in-constructor-and-destructor/' rel='bookmark' title='Permanent Link: 严重避免在构造/析构过程中调用虚函数'>严重避免在构造/析构过程中调用虚函数</a></li>
</ul></p>]]></content:encoded>
			<wfw:commentRss>http://wutiam.net/2010/04/stl-on-the-wrong-way-may-lead-to-hell/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>do...while(0) 的妙用</title>
		<link>http://wutiam.net/2010/03/ingenious-usage-of-do-while-0/</link>
		<comments>http://wutiam.net/2010/03/ingenious-usage-of-do-while-0/#comments</comments>
		<pubDate>Tue, 02 Mar 2010 01:52:10 +0000</pubDate>
		<dc:creator>islet8</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[c++]]></category>

		<guid isPermaLink="false">http://wutiam.net/?p=127</guid>
		<description><![CDATA[在 C++ 中，有三种类型的循环语句：for、while 和 do...while，但是在一般应用中作循环时，我们可能用 for 和 while 要多一些，do...while 相对不受重视。
但是，最近在读我们项目的代码时，却发现了 do...while 的一些十分聪明的用法，不是用来做循环，而是用作其他来提高代码的健壮性。
转载自：http://www.cnblogs.com/flying_bat/archive/2008/01/18/1044693.html
1. do...while(0) 消除 goto 语句
通常，如果在一个函数中开始要分配一些资源，然后在中途执行过程中如果遇到错误则退出函数，当然，退出前先释放资源，我们的代码可能是这样：
[ Version 1 ]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
bool Execute&#40;&#41;
&#123;
   // 分配资源
   int *p = new int;
   bool bOk&#40;true&#41;;
&#160;
   // 执行并进行错误处理
   bOk = func1&#40;&#41;;
   if&#40;!bOk&#41; 
   &#123;
     [...]


Related posts:<ul><li><a href='http://wutiam.net/2009/08/logical-and-or-operation-in-ifdef/' rel='bookmark' title='Permanent Link: #ifdef 中的逻辑与或操作'>#ifdef 中的逻辑与或操作</a></li>
<li><a href='http://wutiam.net/2010/02/let-cpp-new-operator-return-null-when-failed/' rel='bookmark' title='Permanent Link: 让 C++ 的 new 操作失败时返回空指针'>让 C++ 的 new 操作失败时返回空指针</a></li>
<li><a href='http://wutiam.net/2010/07/avoid-private-virtual-member-function-in-cpp-class/' rel='bookmark' title='Permanent Link: 避免在 C++ 类结构中出现私有虚成员函数'>避免在 C++ 类结构中出现私有虚成员函数</a></li>
</ul>]]></description>
			<content:encoded><![CDATA[<p>在 C++ 中，有三种类型的循环语句：for、while 和 do...while，但是在一般应用中作循环时，我们可能用 for 和 while 要多一些，do...while 相对不受重视。<br />
但是，最近在读我们项目的代码时，却发现了 do...while 的一些十分聪明的用法，不是用来做循环，而是用作其他来提高代码的健壮性。</p>
<p><span id="more-127"></span>转载自：<a href="http://www.cnblogs.com/flying_bat/archive/2008/01/18/1044693.html">http://www.cnblogs.com/flying_bat/archive/2008/01/18/1044693.html</a></p>
<p><strong>1. do...while(0) 消除 goto 语句</strong></p>
<p>通常，如果在一个函数中开始要分配一些资源，然后在中途执行过程中如果遇到错误则退出函数，当然，退出前先释放资源，我们的代码可能是这样：</p>
<p>[ Version 1 ]</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
</pre></td><td class="code"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">bool</span> Execute<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
   <span style="color: #666666;">// 分配资源</span>
   <span style="color: #0000ff;">int</span> <span style="color: #000040;">*</span>p <span style="color: #000080;">=</span> <span style="color: #0000dd;">new</span> <span style="color: #0000ff;">int</span><span style="color: #008080;">;</span>
   <span style="color: #0000ff;">bool</span> bOk<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">true</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
&nbsp;
   <span style="color: #666666;">// 执行并进行错误处理</span>
   bOk <span style="color: #000080;">=</span> func1<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
   <span style="color: #0000ff;">if</span><span style="color: #008000;">&#40;</span><span style="color: #000040;">!</span>bOk<span style="color: #008000;">&#41;</span> 
   <span style="color: #008000;">&#123;</span>
      <span style="color: #0000dd;">delete</span> p<span style="color: #008080;">;</span>   
      p <span style="color: #000080;">=</span> <span style="color: #0000ff;">NULL</span><span style="color: #008080;">;</span>
      <span style="color: #0000ff;">return</span> <span style="color: #0000ff;">false</span><span style="color: #008080;">;</span>
   <span style="color: #008000;">&#125;</span>
&nbsp;
   bOk <span style="color: #000080;">=</span> func2<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
   <span style="color: #0000ff;">if</span><span style="color: #008000;">&#40;</span><span style="color: #000040;">!</span>bOk<span style="color: #008000;">&#41;</span> 
   <span style="color: #008000;">&#123;</span>
      <span style="color: #0000dd;">delete</span> p<span style="color: #008080;">;</span>   
      p <span style="color: #000080;">=</span> <span style="color: #0000ff;">NULL</span><span style="color: #008080;">;</span>
      <span style="color: #0000ff;">return</span> <span style="color: #0000ff;">false</span><span style="color: #008080;">;</span>
   <span style="color: #008000;">&#125;</span>
&nbsp;
   bOk <span style="color: #000080;">=</span> func3<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
   <span style="color: #0000ff;">if</span><span style="color: #008000;">&#40;</span><span style="color: #000040;">!</span>bOk<span style="color: #008000;">&#41;</span> 
   <span style="color: #008000;">&#123;</span>
      <span style="color: #0000dd;">delete</span> p<span style="color: #008080;">;</span>   
      p <span style="color: #000080;">=</span> <span style="color: #0000ff;">NULL</span><span style="color: #008080;">;</span>
      <span style="color: #0000ff;">return</span> <span style="color: #0000ff;">false</span><span style="color: #008080;">;</span>
   <span style="color: #008000;">&#125;</span>
&nbsp;
   <span style="color: #666666;">// ..........</span>
&nbsp;
   <span style="color: #666666;">// 执行成功，释放资源并返回</span>
    <span style="color: #0000dd;">delete</span> p<span style="color: #008080;">;</span>   
    p <span style="color: #000080;">=</span> <span style="color: #0000ff;">NULL</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">return</span> <span style="color: #0000ff;">true</span><span style="color: #008080;">;</span>
&nbsp;
<span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

<p>这里一个最大的问题就是代码的冗余，而且我每增加一个操作，就需要做相应的错误处理，非常不灵活。于是我们想到了 goto:</p>
<p>[ Version 2 ]</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
</pre></td><td class="code"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">bool</span> Execute<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
   <span style="color: #666666;">// 分配资源</span>
   <span style="color: #0000ff;">int</span> <span style="color: #000040;">*</span>p <span style="color: #000080;">=</span> <span style="color: #0000dd;">new</span> <span style="color: #0000ff;">int</span><span style="color: #008080;">;</span>
   <span style="color: #0000ff;">bool</span> bOk<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">true</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
&nbsp;
   <span style="color: #666666;">// 执行并进行错误处理</span>
   bOk <span style="color: #000080;">=</span> func1<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
   <span style="color: #0000ff;">if</span><span style="color: #008000;">&#40;</span><span style="color: #000040;">!</span>bOk<span style="color: #008000;">&#41;</span> <span style="color: #0000ff;">goto</span> errorhandle<span style="color: #008080;">;</span>
&nbsp;
   bOk <span style="color: #000080;">=</span> func2<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
   <span style="color: #0000ff;">if</span><span style="color: #008000;">&#40;</span><span style="color: #000040;">!</span>bOk<span style="color: #008000;">&#41;</span> <span style="color: #0000ff;">goto</span> errorhandle<span style="color: #008080;">;</span>
&nbsp;
   bOk <span style="color: #000080;">=</span> func3<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
   <span style="color: #0000ff;">if</span><span style="color: #008000;">&#40;</span><span style="color: #000040;">!</span>bOk<span style="color: #008000;">&#41;</span> <span style="color: #0000ff;">goto</span> errorhandle<span style="color: #008080;">;</span>
&nbsp;
   <span style="color: #666666;">// ..........</span>
&nbsp;
   <span style="color: #666666;">// 执行成功，释放资源并返回</span>
    <span style="color: #0000dd;">delete</span> p<span style="color: #008080;">;</span>   
    p <span style="color: #000080;">=</span> <span style="color: #0000ff;">NULL</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">return</span> <span style="color: #0000ff;">true</span><span style="color: #008080;">;</span>
&nbsp;
errorhandle<span style="color: #008080;">:</span>
    <span style="color: #0000dd;">delete</span> p<span style="color: #008080;">;</span>   
    p <span style="color: #000080;">=</span> <span style="color: #0000ff;">NULL</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">return</span> <span style="color: #0000ff;">false</span><span style="color: #008080;">;</span>
&nbsp;
<span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

<p>代码冗余是消除了，但是我们引入了 C++ 中身份比较微妙的 goto 语句，虽然正确的使用 goto 可以大大提高程序的灵活性与简洁性，但太灵活的东西往往是很危险的，它会让我们的程序捉摸不定，那么怎么才能避免使用 goto 语句，又能消除代码冗余呢，请看 do...while(0) 循环：</p>
<p>[ Version3 ]</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
</pre></td><td class="code"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">bool</span> Execute<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
   <span style="color: #666666;">// 分配资源</span>
   <span style="color: #0000ff;">int</span> <span style="color: #000040;">*</span>p <span style="color: #000080;">=</span> <span style="color: #0000dd;">new</span> <span style="color: #0000ff;">int</span><span style="color: #008080;">;</span>
&nbsp;
   <span style="color: #0000ff;">bool</span> bOk<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">true</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
   <span style="color: #0000ff;">do</span>
   <span style="color: #008000;">&#123;</span>
      <span style="color: #666666;">// 执行并进行错误处理</span>
      bOk <span style="color: #000080;">=</span> func1<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
      <span style="color: #0000ff;">if</span><span style="color: #008000;">&#40;</span><span style="color: #000040;">!</span>bOk<span style="color: #008000;">&#41;</span> <span style="color: #0000ff;">break</span><span style="color: #008080;">;</span>
&nbsp;
      bOk <span style="color: #000080;">=</span> func2<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
      <span style="color: #0000ff;">if</span><span style="color: #008000;">&#40;</span><span style="color: #000040;">!</span>bOk<span style="color: #008000;">&#41;</span> <span style="color: #0000ff;">break</span><span style="color: #008080;">;</span>
&nbsp;
      bOk <span style="color: #000080;">=</span> func3<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
      <span style="color: #0000ff;">if</span><span style="color: #008000;">&#40;</span><span style="color: #000040;">!</span>bOk<span style="color: #008000;">&#41;</span> <span style="color: #0000ff;">break</span><span style="color: #008080;">;</span>
&nbsp;
      <span style="color: #666666;">// ..........</span>
&nbsp;
   <span style="color: #008000;">&#125;</span><span style="color: #0000ff;">while</span><span style="color: #008000;">&#40;</span><span style="color: #0000dd;">0</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
&nbsp;
    <span style="color: #666666;">// 释放资源</span>
    <span style="color: #0000dd;">delete</span> p<span style="color: #008080;">;</span>   
    p <span style="color: #000080;">=</span> <span style="color: #0000ff;">NULL</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">return</span> bOk<span style="color: #008080;">;</span>
&nbsp;
<span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

<p>“漂亮！”， 看代码就行了，啥都不用说了...</p>
<p><strong>2. 宏定义中的 do...while(0)</strong></p>
<p>如果你是 C++ 程序员，我有理由相信你用过，或者接触过，至少听说过MFC, 在 MFC的afx.h 文件里面， 你会发现很多宏定义都是用了 do...while(0) 或 do...while(false)， 比如说：</p>

<div class="wp_syntax"><div class="code"><pre class="cpp" style="font-family:monospace;"><span style="color: #339900;">#define AFXASSUME(cond) do { bool __afx_condVal=!!(cond); ASSERT(__afx_condVal); __analysis_assume(__afx_condVal); } while(0)</span></pre></div></div>

<p>粗看我们就会觉得很奇怪，既然循环里面只执行了一次，我要这个看似多余的 do...while(0) 有什么意义呢？<br />
当然有！<br />
为了看起来更清晰，这里用一个简单点的宏来演示：</p>

<div class="wp_syntax"><div class="code"><pre class="cpp" style="font-family:monospace;"><span style="color: #339900;">#define SAFE_DELETE(p) do{ delete p; p = NULL} while(0)</span></pre></div></div>

<p>假设这里去掉 do...while(0),</p>

<div class="wp_syntax"><div class="code"><pre class="cpp" style="font-family:monospace;"><span style="color: #339900;">#define SAFE_DELETE(p) delete p; p = NULL;</span></pre></div></div>

<p>那么以下代码：</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
</pre></td><td class="code"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">if</span><span style="color: #008000;">&#40;</span><span style="color: #0000ff;">NULL</span> <span style="color: #000040;">!</span><span style="color: #000080;">=</span> p<span style="color: #008000;">&#41;</span> SAFE_DELETE<span style="color: #008000;">&#40;</span>p<span style="color: #008000;">&#41;</span>
<span style="color: #0000ff;">else</span>   ...<span style="color: #0000ff;">do</span> sth...</pre></td></tr></table></div>

<p>就有两个问题：<br />
1) 因为if分支后有两个语句，else分支没有对应的if，编译失败；<br />
2) 假设没有else, SAFE_DELETE中的第二个语句无论if测试是否通过，会永远执行。<br />
你可能发现，为了避免这两个问题，我不一定要用这个令人费解的do...while,  我直接用{}括起来就可以了：</p>

<div class="wp_syntax"><div class="code"><pre class="cpp" style="font-family:monospace;"><span style="color: #339900;">#define SAFE_DELETE(p) { delete p; p = NULL;}</span></pre></div></div>

<p>的确，这样的话上面的问题是不存在了，但是我想对于C++程序员来讲，在每个语句后面加分号是一种约定俗成的习惯，这样的话，以下代码:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
</pre></td><td class="code"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">if</span><span style="color: #008000;">&#40;</span><span style="color: #0000ff;">NULL</span> <span style="color: #000040;">!</span><span style="color: #000080;">=</span> p<span style="color: #008000;">&#41;</span> SAFE_DELETE<span style="color: #008000;">&#40;</span>p<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
<span style="color: #0000ff;">else</span>   ...<span style="color: #0000ff;">do</span> sth...</pre></td></tr></table></div>

<p>其 else 分支就无法通过编译了（原因同上），所以采用 do...while(0) 是做好的选择了。<br />
也许你会说，我们代码的习惯是在每个判断后面加上{}, 就不会有这种问题了，也就不需要 do...while 了，如：</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
</pre></td><td class="code"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">if</span><span style="color: #008000;">&#40;</span>...<span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
<span style="color: #008000;">&#125;</span>
<span style="color: #0000ff;">else</span>
<span style="color: #008000;">&#123;</span>
<span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

<p>诚然，这是一个好的，应该提倡的编程习惯，但一般这样的宏都是作为 library 的一部分出现的，而对于一个 library 的作者，他所要做的就是让其库具有通用性，强壮性，因此他不能有任何对库的使用者的假设，如其编码规范，技术水平等。 </p>


<p>Related posts:<ul><li><a href='http://wutiam.net/2009/08/logical-and-or-operation-in-ifdef/' rel='bookmark' title='Permanent Link: #ifdef 中的逻辑与或操作'>#ifdef 中的逻辑与或操作</a></li>
<li><a href='http://wutiam.net/2010/02/let-cpp-new-operator-return-null-when-failed/' rel='bookmark' title='Permanent Link: 让 C++ 的 new 操作失败时返回空指针'>让 C++ 的 new 操作失败时返回空指针</a></li>
<li><a href='http://wutiam.net/2010/07/avoid-private-virtual-member-function-in-cpp-class/' rel='bookmark' title='Permanent Link: 避免在 C++ 类结构中出现私有虚成员函数'>避免在 C++ 类结构中出现私有虚成员函数</a></li>
</ul></p>]]></content:encoded>
			<wfw:commentRss>http://wutiam.net/2010/03/ingenious-usage-of-do-while-0/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>让 C++ 的 new 操作失败时返回空指针</title>
		<link>http://wutiam.net/2010/02/let-cpp-new-operator-return-null-when-failed/</link>
		<comments>http://wutiam.net/2010/02/let-cpp-new-operator-return-null-when-failed/#comments</comments>
		<pubDate>Thu, 25 Feb 2010 01:33:52 +0000</pubDate>
		<dc:creator>islet8</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[c++]]></category>

		<guid isPermaLink="false">http://wutiam.net/?p=124</guid>
		<description><![CDATA[C 中如果创建一个对象失败，就会返回空指针。但是对于 C++ 就不一样了，new 是不应返回空指针的，书上的推荐做法是在构造函数里抛异常。
当不想引入异常机制的时候，一般的做法是在构造器里啥都不做（最多做个变量初始化），加一个 Init() 函数来完成真正的初始化工作。
然而这样就使得每次创建一个对象，都要执行两步（new+init），总不是太方便，其实 C++ 的 new 操作符是带参的，可以通过“new(std::nothrow) CXxx”的方式让 new 失败时返回 null 指针，来标记失败（而不是抛出异常）。


Related posts:do...while(0) 的妙用
避免在 C++ 类结构中出现私有虚成员函数
严重避免在构造/析构过程中调用虚函数



Related posts:<ul><li><a href='http://wutiam.net/2010/03/ingenious-usage-of-do-while-0/' rel='bookmark' title='Permanent Link: do...while(0) 的妙用'>do...while(0) 的妙用</a></li>
<li><a href='http://wutiam.net/2010/07/avoid-private-virtual-member-function-in-cpp-class/' rel='bookmark' title='Permanent Link: 避免在 C++ 类结构中出现私有虚成员函数'>避免在 C++ 类结构中出现私有虚成员函数</a></li>
<li><a href='http://wutiam.net/2010/01/prevent-invoking-virtual-functions-in-constructor-and-destructor/' rel='bookmark' title='Permanent Link: 严重避免在构造/析构过程中调用虚函数'>严重避免在构造/析构过程中调用虚函数</a></li>
</ul>]]></description>
			<content:encoded><![CDATA[<p>C 中如果创建一个对象失败，就会返回空指针。但是对于 C++ 就不一样了，new 是不应返回空指针的，书上的推荐做法是在构造函数里抛异常。<br />
当不想引入异常机制的时候，一般的做法是在构造器里啥都不做（最多做个变量初始化），加一个 Init() 函数来完成真正的初始化工作。<br />
然而这样就使得每次创建一个对象，都要执行两步（new+init），总不是太方便，其实 C++ 的 new 操作符是带参的，可以通过“<strong>new(std::nothrow) CXxx</strong>”的方式让 new 失败时返回 null 指针，来标记失败（而不是抛出异常）。</p>


<p>Related posts:<ul><li><a href='http://wutiam.net/2010/03/ingenious-usage-of-do-while-0/' rel='bookmark' title='Permanent Link: do...while(0) 的妙用'>do...while(0) 的妙用</a></li>
<li><a href='http://wutiam.net/2010/07/avoid-private-virtual-member-function-in-cpp-class/' rel='bookmark' title='Permanent Link: 避免在 C++ 类结构中出现私有虚成员函数'>避免在 C++ 类结构中出现私有虚成员函数</a></li>
<li><a href='http://wutiam.net/2010/01/prevent-invoking-virtual-functions-in-constructor-and-destructor/' rel='bookmark' title='Permanent Link: 严重避免在构造/析构过程中调用虚函数'>严重避免在构造/析构过程中调用虚函数</a></li>
</ul></p>]]></content:encoded>
			<wfw:commentRss>http://wutiam.net/2010/02/let-cpp-new-operator-return-null-when-failed/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>严重避免在构造/析构过程中调用虚函数</title>
		<link>http://wutiam.net/2010/01/prevent-invoking-virtual-functions-in-constructor-and-destructor/</link>
		<comments>http://wutiam.net/2010/01/prevent-invoking-virtual-functions-in-constructor-and-destructor/#comments</comments>
		<pubDate>Fri, 29 Jan 2010 03:28:16 +0000</pubDate>
		<dc:creator>islet8</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[c++]]></category>

		<guid isPermaLink="false">http://wutiam.net/?p=123</guid>
		<description><![CDATA[之前只知道在 C++ 的构造器中，调用虚函数（非纯虚函数）不会出现多态的情况，却想当然认为既然析构器可以被声明为虚“函数”，那么析构器应该是能实现虚函数调用的的多态结果的。
事实证明，我又被蒙骗了！
构造器/析构器不会在调用虚函数时执行子类的重载实现，而且更危险的是当构造器/析构器“间接地”调用了虚函数（例如调用了一个非虚函数，但这个函数里调用了虚函数），不仅子类的重载实现不会被执行，而且还很难发现这种 bug。
所以，切记，切忌在构造器/析构器中直接或间接地调用任何虚函数！（单是在构造器/析构器中直接或间接地调用其他对象的虚函数并不受影响）


Related posts:避免在 C++ 类结构中出现私有虚成员函数
do...while(0) 的妙用
让 C++ 的 new 操作失败时返回空指针



Related posts:<ul><li><a href='http://wutiam.net/2010/07/avoid-private-virtual-member-function-in-cpp-class/' rel='bookmark' title='Permanent Link: 避免在 C++ 类结构中出现私有虚成员函数'>避免在 C++ 类结构中出现私有虚成员函数</a></li>
<li><a href='http://wutiam.net/2010/03/ingenious-usage-of-do-while-0/' rel='bookmark' title='Permanent Link: do...while(0) 的妙用'>do...while(0) 的妙用</a></li>
<li><a href='http://wutiam.net/2010/02/let-cpp-new-operator-return-null-when-failed/' rel='bookmark' title='Permanent Link: 让 C++ 的 new 操作失败时返回空指针'>让 C++ 的 new 操作失败时返回空指针</a></li>
</ul>]]></description>
			<content:encoded><![CDATA[<p>之前只知道在 C++ 的构造器中，调用虚函数（非纯虚函数）不会出现多态的情况，却想当然认为既然析构器可以被声明为虚“函数”，那么析构器应该是能实现虚函数调用的的多态结果的。<br />
事实证明，我又被蒙骗了！</p>
<p>构造器/析构器不会在调用虚函数时执行子类的重载实现，而且更危险的是当构造器/析构器“间接地”调用了虚函数（例如调用了一个非虚函数，但这个函数里调用了虚函数），不仅子类的重载实现不会被执行，而且还很难发现这种 bug。</p>
<p>所以，切记，<strong>切忌在构造器/析构器中直接或间接地调用任何虚函数！</strong>（单是在构造器/析构器中直接或间接地调用其他对象的虚函数并不受影响）</p>


<p>Related posts:<ul><li><a href='http://wutiam.net/2010/07/avoid-private-virtual-member-function-in-cpp-class/' rel='bookmark' title='Permanent Link: 避免在 C++ 类结构中出现私有虚成员函数'>避免在 C++ 类结构中出现私有虚成员函数</a></li>
<li><a href='http://wutiam.net/2010/03/ingenious-usage-of-do-while-0/' rel='bookmark' title='Permanent Link: do...while(0) 的妙用'>do...while(0) 的妙用</a></li>
<li><a href='http://wutiam.net/2010/02/let-cpp-new-operator-return-null-when-failed/' rel='bookmark' title='Permanent Link: 让 C++ 的 new 操作失败时返回空指针'>让 C++ 的 new 操作失败时返回空指针</a></li>
</ul></p>]]></content:encoded>
			<wfw:commentRss>http://wutiam.net/2010/01/prevent-invoking-virtual-functions-in-constructor-and-destructor/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PBRT 学习：安装编译</title>
		<link>http://wutiam.net/2009/09/pbrt-study-install-and-build/</link>
		<comments>http://wutiam.net/2009/09/pbrt-study-install-and-build/#comments</comments>
		<pubDate>Wed, 30 Sep 2009 06:32:48 +0000</pubDate>
		<dc:creator>islet8</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[图形图像]]></category>

		<guid isPermaLink="false">http://wutiam.net/?p=116</guid>
		<description><![CDATA[去年在前公司看着 leader 用 PBRT 做基于 DX11/SM5.0 的 ray tracing 实验时，还懵懂得云里雾里。而我现在的 manager，在读研的时候就已经在研究 PBRT 了。我， out 了！最近由于工作的原因，终于开始着手学习 PBRT，而这玩意第一道关卡就是安装编译中的一堆问题，记录以备不时只需。
网上关于 PBRT 的资料基本都是 1.03 或更早的，而且基本都跳过了自动生成代码的预处理阶段。这次下载来的最新 pbrt-src-1.04.zip for Windows 虽然在其 release note 里说“a number of bugs and incompatabilities have been fixed”，但从我安装编译的经过来看，问题似乎更多了（斯坦福的大大们不应该这么粗心吧）。
首先把下载的文件解压到任意目录下，我这是“D:\Program Files\pbrt-1.04”，不过推荐还是放到分区根目录或者文件夹名不含空格的路径下，否则后面会多几个体力活。
PBRT 使用了 Bison 和 Flex 这两个工具来生成用于解析 pbrt 脚本文件的代码文件（这话有点绕哈），而这两个工具本是 Linux 下的，现在都有大大做了 Windows 版的移植（Bison for Windows，Flex for Windows）。分别把 Bison Binaries 中的 \bin [...]


Related posts:<ul><li><a href='http://wutiam.net/2009/04/problem-of-compiling-wowmodelviewer/' rel='bookmark' title='Permanent Link: WoW Model Viewer 的编译问题'>WoW Model Viewer 的编译问题</a></li>
<li><a href='http://wutiam.net/2009/02/how-to-decide-whether-a-point-is-inside-a-triangle/' rel='bookmark' title='Permanent Link: 判断一个点是否在 2D 三角形内'>判断一个点是否在 2D 三角形内</a></li>
<li><a href='http://wutiam.net/2009/04/3d-coordinates/' rel='bookmark' title='Permanent Link: 3D Coordinates'>3D Coordinates</a></li>
</ul>]]></description>
			<content:encoded><![CDATA[<p>去年在前公司看着 leader 用 <a title="Physically Based Rendering" href="http://www.pbrt.org/">PBRT</a> 做基于 DX11/SM5.0 的 <a title="光线跟踪 - Wikipedia" href="http://zh.wikipedia.org/zh-cn/%E5%85%89%E7%BA%BF%E8%B7%9F%E8%B8%AA">ray tracing</a> 实验时，还懵懂得云里雾里。而我现在的 manager，在读研的时候就已经在研究 PBRT 了。我， out 了！最近由于工作的原因，终于开始着手学习 PBRT，而这玩意第一道关卡就是安装编译中的一堆问题，记录以备不时只需。</p>
<p>网上关于 PBRT 的资料基本都是 1.03 或更早的，而且基本都跳过了自动生成代码的预处理阶段。这次下载来的最新 <a href="http://www.pbrt.org/src/pbrt-src-1.04.zip">pbrt-src-1.04.zip for Windows</a> 虽然在其 release note 里说“a number of bugs and incompatabilities have been fixed”，但从我安装编译的经过来看，问题似乎更多了（斯坦福的大大们不应该这么粗心吧）。</p>
<p>首先把下载的文件解压到任意目录下，我这是“D:\Program Files\pbrt-1.04”，不过<strong>推荐还是放到分区根目录或者文件夹名不含空格的路径下</strong>，否则后面会多几个体力活。</p>
<p>PBRT 使用了 Bison 和 Flex 这两个工具来生成用于解析 pbrt 脚本文件的代码文件（这话有点绕哈），而这两个工具本是 Linux 下的，现在都有大大做了 Windows 版的移植（<a href="http://gnuwin32.sourceforge.net/packages/bison.htm">Bison for Windows</a>，<a href="http://gnuwin32.sourceforge.net/packages/flex.htm">Flex for Windows</a>）。分别把 Bison Binaries 中的 \bin 和 \share、Bison Dependencies 中的 \bin、Flex Binaries 中的 \bin 目录解压到任意目录下，我这是“D:\GnuWin32”。</p>
<p>这时 PBRT 还是不能编译的，原因是 1.04 中移除了对 <a href="http://www.openexr.com/">OpenEXR</a> 工具包的包含。OpenEXR 本身是<a title="HDR文件格式简介" href="http://blog.csdn.net/zzzGoogle/archive/2007/05/18/1615691.aspx">三大 HDRI 格式</a>之一，另外两种格式在以前我都处理过，而对 EXR 格式不熟，这里暂时也不做深究。OpenEXR 工具包可以在其<a title="OpenEXR Downloads" href="http://www.openexr.com/downloads.html">官网下载</a>（最新的 1.5.0 没有 VS2005 的预编译版本，我偷懒就直接下 <a href="http://download.savannah.nongnu.org/releases/openexr/openexr-1.4.0-vs2005.zip">openexr-1.4.0-vs2005.zip</a> 了），也可以从 PBRT 1.03 zip 包中直接拿来用，然后整个解压出来，我这是“D:\Program Files\pbrt-1.04\openexr-1.4.0-vs2005”。这还没完，无论是官网还是 PBRT 1.03 里的 OpenEXR 工具包，在 \lib 文件夹下都缺少 zdll.lib 这个文件，去 <a href="http://www.zlib.net/">zlib 首页</a>下载 zlib compiled DLL zipfile，把压缩包中的 \lib 解压到 OpenEXR 所在文件夹下。</p>
<p><span id="more-116"></span>接下来就可以用 VS2005 打开 PBRT 文件夹下的 \win32\pbrt.sln，这时先别急着按 F7，工程属性里还有不少设置需要修改。</p>
<p>先展开 core 工程下的 Parser Files 文件夹，分别打开 pbrtlex.l 和 pbrtparse.y 两个文件的属性对话框，编辑 Custom Build Step | General | Command Line，重新指定 flex 和 bison 程序的位置及参数，我这是：</p>

<div class="wp_syntax"><div class="code"><pre class="txt" style="font-family:monospace;">&quot;D:\GnuWin32\bin1\flex.exe&quot; -o&quot;$(InputDir)/$(InputName).cpp&quot; &quot;$(InputPath)&quot;
&nbsp;
&quot;D:\GnuWin32\bin\bison.exe&quot; -d -v -t -o&quot;$(InputDir)/$(InputName).cpp&quot; &quot;$(InputPath)&quot;</pre></div></div>

<p>注意这里所有的路径都被引号包裹了，这是由于我把 PBRT 放在“Program Files”这个文件夹下，如前面所述，本来这些引号可以不需要加的，后面的设置项也有同样问题，不一一注明了。检测这个步骤是否修改正确，可以直接编译这两个奇怪的文件，如果能在 \core 文件夹下生成 pbrtlex.cpp、pbrtparse.cpp 和 pbrtparse.hpp 这三个文件，则 OK 了，否则会有关于“error: A tool returned an error code from "Lexing pbrtlex"”或“error: A tool returned an error code from "Yacc'ing pbrtparse"”的报错。</p>
<p>过了上面这一步，其实离成功距离就不远了。按照<a href="http://www.pbrt.org/faq.php#faqs_build-win32_unistd">官网 FAQ</a> 里的说法，在 \core 文件夹下创建一个空的 unistd.h 文件，而不是注释掉 \core\pbrtlex.cpp 里的“#include ”这行，否则每次编译 pbrtlex.cpp 后还得再改一次，麻烦。还有一个很“粗心”的错，在 core 工程属性里的 Linker | Input | Additional Dependencies，居然漏写了“IlmThread.lib”这个库，加上就好。如果不嫌累，还可以把 Debug 模式下的几个库（Half.lib、Iex.lib、IlmImf.lib、IlmThread.lib、Imath.lib）改为 Half_d.lib、Iex_d.lib、IlmImf_d.lib、IlmThread_d.lib、Imath_d.lib。</p>
<p>如果 build 到最后，在 render 这个工程的 Post-Build Event 中报类似“Copying zlib1.dll to ……”失败的错误，则应该是由于路径包含空格导致其工程属性里 Build Events | Post-Build Event | Command Line 的展开路径没法正确访问引起的错误，加上引号就好了。</p>
<p>Well done! 最后，在系统环境变量里，加一项“PBRT_SEARCHPATH”，值为“D:\Program Files\pbrt-1.04\win32\Projects\Release”，否则 pbrt 程序是跑不起来的。现在，下载一个<a title="PBRT Input File Format" href="http://www.cse.ohio-state.edu/~parent/classes/782/labs/PBRT/pbrtscene.html">测试用的 pbrt 脚本文件</a>，再写个批处理脚本 pbrt.cmd，都放到 PBRT 文件夹下的 \scenes 文件夹下，来测试下 pbrt 程序吧，批处理脚本如下：</p>

<div class="wp_syntax"><div class="code"><pre class="txt" style="font-family:monospace;">SET PATH=%PATH%;%PBRT_SEARCHPATH%
&nbsp;
pbrt.exe sharp.pbrt
&quot;..\openexr-1.4.0-vs2005\bin\exrdisplay.exe&quot; sharp.exr</pre></div></div>

<p>P.S. 据说 PBRT 无法在 VS2008+ 下正常工作，未经测试。</p>


<p>Related posts:<ul><li><a href='http://wutiam.net/2009/04/problem-of-compiling-wowmodelviewer/' rel='bookmark' title='Permanent Link: WoW Model Viewer 的编译问题'>WoW Model Viewer 的编译问题</a></li>
<li><a href='http://wutiam.net/2009/02/how-to-decide-whether-a-point-is-inside-a-triangle/' rel='bookmark' title='Permanent Link: 判断一个点是否在 2D 三角形内'>判断一个点是否在 2D 三角形内</a></li>
<li><a href='http://wutiam.net/2009/04/3d-coordinates/' rel='bookmark' title='Permanent Link: 3D Coordinates'>3D Coordinates</a></li>
</ul></p>]]></content:encoded>
			<wfw:commentRss>http://wutiam.net/2009/09/pbrt-study-install-and-build/feed/</wfw:commentRss>
		<slash:comments>18</slash:comments>
		</item>
		<item>
		<title>#ifdef 中的逻辑与或操作</title>
		<link>http://wutiam.net/2009/08/logical-and-or-operation-in-ifdef/</link>
		<comments>http://wutiam.net/2009/08/logical-and-or-operation-in-ifdef/#comments</comments>
		<pubDate>Thu, 20 Aug 2009 02:40:05 +0000</pubDate>
		<dc:creator>islet8</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[c++]]></category>

		<guid isPermaLink="false">http://wutiam.net/?p=109</guid>
		<description><![CDATA[原本用宏定义包起来的代码类似如下：

#ifndef A
// codes
#endif // A

现在要加入一个宏定义 B，实现类似这样的条件判断（显然实际上这样是不行的）：

#ifndef A &#38;&#38; ifdef B

其实应该这样：

#if (!defined A) &#38;&#38; (defined B)
// codes
#endif // !A &#38;&#38; B

这就修正了之前一直以为的“既生 #ifdef，何生 #if defined”的思维，其实还是有差别的。


Related posts:避免在 C++ 类结构中出现私有虚成员函数
do...while(0) 的妙用
让 C++ 的 new 操作失败时返回空指针



Related posts:<ul><li><a href='http://wutiam.net/2010/07/avoid-private-virtual-member-function-in-cpp-class/' rel='bookmark' title='Permanent Link: 避免在 C++ 类结构中出现私有虚成员函数'>避免在 C++ 类结构中出现私有虚成员函数</a></li>
<li><a href='http://wutiam.net/2010/03/ingenious-usage-of-do-while-0/' rel='bookmark' title='Permanent Link: do...while(0) 的妙用'>do...while(0) 的妙用</a></li>
<li><a href='http://wutiam.net/2010/02/let-cpp-new-operator-return-null-when-failed/' rel='bookmark' title='Permanent Link: 让 C++ 的 new 操作失败时返回空指针'>让 C++ 的 new 操作失败时返回空指针</a></li>
</ul>]]></description>
			<content:encoded><![CDATA[<p>原本用宏定义包起来的代码类似如下：</p>

<div class="wp_syntax"><div class="code"><pre class="cpp" style="font-family:monospace;"><span style="color: #339900;">#ifndef A</span>
<span style="color: #666666;">// codes</span>
<span style="color: #339900;">#endif // A</span></pre></div></div>

<p>现在要加入一个宏定义 B，实现类似这样的条件判断（显然实际上这样是不行的）：</p>

<div class="wp_syntax"><div class="code"><pre class="cpp" style="font-family:monospace;"><span style="color: #339900;">#ifndef A &amp;&amp; ifdef B</span></pre></div></div>

<p>其实应该这样：</p>

<div class="wp_syntax"><div class="code"><pre class="cpp" style="font-family:monospace;"><span style="color: #339900;">#if (!defined A) &amp;&amp; (defined B)</span>
<span style="color: #666666;">// codes</span>
<span style="color: #339900;">#endif // !A &amp;&amp; B</span></pre></div></div>

<p>这就修正了之前一直以为的“既生 #ifdef，何生 #if defined”的思维，其实还是<a title="#if define (abc)与#ifdef abc 有什么区别?" href="http://zhidao.baidu.com/question/40577172.html">有差别的</a>。</p>


<p>Related posts:<ul><li><a href='http://wutiam.net/2010/07/avoid-private-virtual-member-function-in-cpp-class/' rel='bookmark' title='Permanent Link: 避免在 C++ 类结构中出现私有虚成员函数'>避免在 C++ 类结构中出现私有虚成员函数</a></li>
<li><a href='http://wutiam.net/2010/03/ingenious-usage-of-do-while-0/' rel='bookmark' title='Permanent Link: do...while(0) 的妙用'>do...while(0) 的妙用</a></li>
<li><a href='http://wutiam.net/2010/02/let-cpp-new-operator-return-null-when-failed/' rel='bookmark' title='Permanent Link: 让 C++ 的 new 操作失败时返回空指针'>让 C++ 的 new 操作失败时返回空指针</a></li>
</ul></p>]]></content:encoded>
			<wfw:commentRss>http://wutiam.net/2009/08/logical-and-or-operation-in-ifdef/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>让 Visual Studio 2005 自动生成 Manifest</title>
		<link>http://wutiam.net/2009/08/manifest-dependencies-in-visual-studio-2005/</link>
		<comments>http://wutiam.net/2009/08/manifest-dependencies-in-visual-studio-2005/#comments</comments>
		<pubDate>Wed, 12 Aug 2009 15:34:30 +0000</pubDate>
		<dc:creator>islet8</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[vs/vc++]]></category>

		<guid isPermaLink="false">http://wutiam.net/?p=75</guid>
		<description><![CDATA[微软同学永远是个把简单问题复杂化的孩子，这不，当年为了在 Windows XP 中同时支持两套控件风格（新的 XP 风格和旧的 95/98 风格），“发明”了 .manifest 这么个玩意，使以前的老程序也能自动使用上新的控件风格。
然而在 VS 里，微软并不是总是默认帮我们自动生成这个破玩意儿。最早的办法就是手写一个 .manifest XML 文件，不过这个办法在 VS 2005 编译出来的程序里似乎并不起作用。当然，新方法总是随之而出的，而且很“简单”（绕了一大圈又回来了）：
在 Project Properties 对话框的 Configuration Properties &#124; Linker &#124; Manifest File &#124; Additional Manifest Dependencies 选项里，填入：

&#34;type='Win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='X86' publicKeyToken='6595b64144ccf1df' language='*'&#34;

或者在程序里直接写下如下代码：

#pragma comment(linker, &#34;\&#34;/manifestdependency:type='Win32' name='Test.Research.SampleAssembly' version='6.0.0.0' processorArchitecture='X86' publicKeyToken='0000000000000000' language='*'\&#34;&#34;)

太阳又照常东升西落了  


Related posts:征服 Visual Studio 的 Editor
Visual Studio 2008 无法进入修复/卸载界面的解决办法
IE8 [...]


Related posts:<ul><li><a href='http://wutiam.net/2009/05/tips-of-visual-studio-editor/' rel='bookmark' title='Permanent Link: 征服 Visual Studio 的 Editor'>征服 Visual Studio 的 Editor</a></li>
<li><a href='http://wutiam.net/2009/06/uninstalling-visual-studio-2008-may-fail-to-load-setup-components/' rel='bookmark' title='Permanent Link: Visual Studio 2008 无法进入修复/卸载界面的解决办法'>Visual Studio 2008 无法进入修复/卸载界面的解决办法</a></li>
<li><a href='http://wutiam.net/2009/04/some-vs2005-and-vs2008-wizards-pop-up-script-error/' rel='bookmark' title='Permanent Link: IE8 引发 VS 2005/2008 向导出错的解决方案'>IE8 引发 VS 2005/2008 向导出错的解决方案</a></li>
</ul>]]></description>
			<content:encoded><![CDATA[<p>微软同学永远是个把简单问题复杂化的孩子，这不，当年为了在 Windows XP 中同时支持两套控件风格（新的 XP 风格和旧的 95/98 风格），“发明”了 .manifest 这么个玩意，使以前的老程序也能自动使用上新的控件风格。</p>
<p>然而在 VS 里，微软并不是总是默认帮我们自动生成这个破玩意儿。最早的办法就是手写一个 .manifest XML 文件，不过这个办法在 VS 2005 编译出来的程序里似乎并不起作用。当然，新方法总是随之而出的，而且很“简单”（绕了一大圈又回来了）：</p>
<p>在 Project Properties 对话框的 Configuration Properties | Linker | Manifest File | Additional Manifest Dependencies 选项里，填入：</p>

<div class="wp_syntax"><div class="code"><pre class="txt" style="font-family:monospace;">&quot;type='Win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='X86' publicKeyToken='6595b64144ccf1df' language='*'&quot;</pre></div></div>

<p>或者在程序里直接写下如下代码：</p>

<div class="wp_syntax"><div class="code"><pre class="cpp" style="font-family:monospace;"><span style="color: #339900;">#pragma comment(linker, &quot;\&quot;/manifestdependency:type='Win32' name='Test.Research.SampleAssembly' version='6.0.0.0' processorArchitecture='X86' publicKeyToken='0000000000000000' language='*'\&quot;&quot;)</span></pre></div></div>

<p>太阳又照常东升西落了 <img src='http://wutiam.net/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>


<p>Related posts:<ul><li><a href='http://wutiam.net/2009/05/tips-of-visual-studio-editor/' rel='bookmark' title='Permanent Link: 征服 Visual Studio 的 Editor'>征服 Visual Studio 的 Editor</a></li>
<li><a href='http://wutiam.net/2009/06/uninstalling-visual-studio-2008-may-fail-to-load-setup-components/' rel='bookmark' title='Permanent Link: Visual Studio 2008 无法进入修复/卸载界面的解决办法'>Visual Studio 2008 无法进入修复/卸载界面的解决办法</a></li>
<li><a href='http://wutiam.net/2009/04/some-vs2005-and-vs2008-wizards-pop-up-script-error/' rel='bookmark' title='Permanent Link: IE8 引发 VS 2005/2008 向导出错的解决方案'>IE8 引发 VS 2005/2008 向导出错的解决方案</a></li>
</ul></p>]]></content:encoded>
			<wfw:commentRss>http://wutiam.net/2009/08/manifest-dependencies-in-visual-studio-2005/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Visual Studio 2008 无法进入修复/卸载界面的解决办法</title>
		<link>http://wutiam.net/2009/06/uninstalling-visual-studio-2008-may-fail-to-load-setup-components/</link>
		<comments>http://wutiam.net/2009/06/uninstalling-visual-studio-2008-may-fail-to-load-setup-components/#comments</comments>
		<pubDate>Tue, 09 Jun 2009 14:41:05 +0000</pubDate>
		<dc:creator>islet8</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[vs/vc++]]></category>

		<guid isPermaLink="false">http://wutiam.net/?p=103</guid>
		<description><![CDATA[最近需要在家办公，硬盘空间又不够了，只好卸了 VS2008 重装 VS2005，结果无论通过控制面板的卸载还是通过光盘的 autorun.exe，都在检查配置的时候弹出“A problem has been encountered while loading the setup  components. Canceling setup.”的错误对话框，然后就自动退出了，连修复的机会都完全不给……
放狗在 MSDN 的论坛里搜到了这篇帖子里 George175 给出的解决办法，原来是 VS2008 的一个 patch 捣的乱，直接进控制面板，进入添加/删除程序（或卸载程序），左边选择查看/卸载更新，找到“Hot Fix for Visual Studio 2008”这个玩意儿，直接咔嚓掉。
然后，VS2008 就能正常卸载了。
另，微软的一位同学说安装 VS2008 SP1 也能解决，没有验证，应该不会有错。


Related posts:IE8 引发 VS 2005/2008 向导出错的解决方案
征服 Visual Studio 的 Editor
让 Visual Studio 2005 自动生成 Manifest



Related posts:<ul><li><a href='http://wutiam.net/2009/04/some-vs2005-and-vs2008-wizards-pop-up-script-error/' rel='bookmark' title='Permanent Link: IE8 引发 VS 2005/2008 向导出错的解决方案'>IE8 引发 VS 2005/2008 向导出错的解决方案</a></li>
<li><a href='http://wutiam.net/2009/05/tips-of-visual-studio-editor/' rel='bookmark' title='Permanent Link: 征服 Visual Studio 的 Editor'>征服 Visual Studio 的 Editor</a></li>
<li><a href='http://wutiam.net/2009/08/manifest-dependencies-in-visual-studio-2005/' rel='bookmark' title='Permanent Link: 让 Visual Studio 2005 自动生成 Manifest'>让 Visual Studio 2005 自动生成 Manifest</a></li>
</ul>]]></description>
			<content:encoded><![CDATA[<p>最近需要在家办公，硬盘空间又不够了，只好卸了 VS2008 重装 VS2005，结果无论通过控制面板的卸载还是通过光盘的 autorun.exe，都在检查配置的时候弹出“<span>A problem has been encountered while loading the setup  components. Canceling setup.</span>”的错误对话框，然后就自动退出了，连修复的机会都完全不给……</p>
<p>放狗在 MSDN 的论坛里搜到了<a title="A problem has been encountered while loading the setup components. Canceling setup." href="http://social.msdn.microsoft.com/Forums/en-US/Vsexpressinstall/thread/588c15f1-8a4d-48f6-87db-faeee1219bb2">这篇</a>帖子里 George175 给出的解决办法，原来是 VS2008 的一个 patch 捣的乱，直接进控制面板，进入添加/删除程序（或卸载程序），左边选择查看/卸载更新，找到“Hot Fix for Visual Studio 2008”这个玩意儿，直接咔嚓掉。</p>
<p>然后，VS2008 就能正常卸载了。</p>
<p>另，微软的一位<a title="Adding features to Visual Studio 2008 may fail to load setup components" href="http://blogs.msdn.com/heaths/archive/2008/10/06/adding-features-to-visual-studio-2008-may-fail-to-load-setup-components.aspx">同学</a>说安装 VS2008 SP1 也能解决，没有验证，应该不会有错。</p>


<p>Related posts:<ul><li><a href='http://wutiam.net/2009/04/some-vs2005-and-vs2008-wizards-pop-up-script-error/' rel='bookmark' title='Permanent Link: IE8 引发 VS 2005/2008 向导出错的解决方案'>IE8 引发 VS 2005/2008 向导出错的解决方案</a></li>
<li><a href='http://wutiam.net/2009/05/tips-of-visual-studio-editor/' rel='bookmark' title='Permanent Link: 征服 Visual Studio 的 Editor'>征服 Visual Studio 的 Editor</a></li>
<li><a href='http://wutiam.net/2009/08/manifest-dependencies-in-visual-studio-2005/' rel='bookmark' title='Permanent Link: 让 Visual Studio 2005 自动生成 Manifest'>让 Visual Studio 2005 自动生成 Manifest</a></li>
</ul></p>]]></content:encoded>
			<wfw:commentRss>http://wutiam.net/2009/06/uninstalling-visual-studio-2008-may-fail-to-load-setup-components/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
	</channel>
</rss>
