<?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>Lost HIT - Zealot&#039;s Blog &#187; C/C++</title>
	<atom:link href="http://blog.losthit.com/archives/category/computer-science/cc/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.losthit.com</link>
	<description>关注 linux/c/c++/python/web开发,互联网数据抓取与挖掘</description>
	<lastBuildDate>Tue, 31 Jan 2012 09:27:29 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>海盗分金问题分析与解决</title>
		<link>http://blog.losthit.com/archives/pirate-and-gold/</link>
		<comments>http://blog.losthit.com/archives/pirate-and-gold/#comments</comments>
		<pubDate>Sun, 01 Aug 2010 16:48:29 +0000</pubDate>
		<dc:creator>Zealot</dc:creator>
				<category><![CDATA[Algorithm]]></category>
		<category><![CDATA[C/C++]]></category>
		<category><![CDATA[Computer Science]]></category>
		<category><![CDATA[nim]]></category>
		<category><![CDATA[代码]]></category>
		<category><![CDATA[海盗分金]]></category>
		<category><![CDATA[算法]]></category>

		<guid isPermaLink="false">http://blog.losthit.com/?p=329</guid>
		<description><![CDATA[海盗分金问题分析与解决 ——Nim取子问题变形后的解决方案 全文下载链接：海盗分金问题分析与解决.pdf Author: Zealot Ke(kejie[at]kuxun.cn) Date: 2010/7/30 背景 强哥邮件发出一个题目 有5个海盗,特别的... ]]></description>
			<content:encoded><![CDATA[<h2>海盗分金问题分析与解决</h2>
<p style="text-align: right;">——Nim取子问题变形后的解决方案</p>
<p>
全文下载链接：<a href='http://blog.losthit.com/wp-content/uploads/2010/08/海盗分金问题分析与解决.pdf'>海盗分金问题分析与解决.pdf</a>
</p>
<p>Author:	Zealot Ke(kejie[at]kuxun.cn)<br />
Date:	2010/7/30</p>
<h3>背景</h3>
<p>强哥邮件发出一个题目</p>
<ol>
<li>有5个海盗,特别的残忍,特别的聪明</li>
<li>他们抢了100个金币,要进行分配,每个人都想分配足够多的金币,他们寸步不让.分配顺序是:5号海盗-&gt;4号海盗…1号海盗,即是:先由5号海盗决定如何分配,若分配不均,5号被扔下海,4号海盗再决定如何分配,依次类推.</li>
<li>如果没有二分之一或以上的海盗同意,分配人将被其他人扔下大海.</li>
<li>假如你是5号海盗,你会如何分配金币.确保自己不会被扔下大海,而且让其他4个海盗心服口服.</li>
</ol>
<h3>定义问题</h3>
<p>5号海盗必须按照上述规则，找出最优分配方案，否则将被其他人扔下大海。</p>
<h3>当前状态</h3>
<p>正确分配方案还没出来，必须尽快找出最优解。</p>
<h3>分析</h3>
<p>典型的nim取子问题的变形，采用倒推方式即可找到最优解。</p>
<h3>制定解决方案</h3>
<p>倒推方法如下所示</p>
<ol>
<li>如果只有一个海盗，如何分配？</li>
<li>如果有两个海盗，如何分配？</li>
<li>如果有n个海盗，每个海盗至少需要几个人同意？找出n-1个海盗情况下的分配方案中，需要收买多少海盗？最低需要多少金币？</li>
</ol>
<h3>实现解决方案</h3>
<p>倒推方法实现如下表所示，每一行表示一种人数情况下的分配方案，也即，最后一行给出5号海盗的分配方案。</p>
<div id="attachment_334" class="wp-caption alignleft" style="width: 706px"><a href="http://blog.losthit.com/wp-content/uploads/2010/08/nim-analytics-table.jpg"><img class="size-full wp-image-334" title="分配方案倒推分析表" src="http://blog.losthit.com/wp-content/uploads/2010/08/nim-analytics-table.jpg" alt="分配方案倒推分析表" width="696" height="664" /></a><p class="wp-caption-text">分配方案倒推分析表</p></div>
<p>注意：从表中可以看出聪明是大前提，当然残忍也是。nim取子游戏向来是君子游戏，没有这个前提的话，后面的海盗不按套路出牌就不可能有最优解。</p>
<h3>标准化解决方案</h3>
<p>从上表不难看出规律，也即，自己拿尽可能多的金币，同时保证后面的人依次分配0、1交错的金币数。规范化命题如下<br />
<strong>*命题</strong>: 假设对于n个聪明、残忍的海盗（n≥1），抢了Gold个金币，要进行分配，每个人都想分配足够多的金币，他们寸步不让。分配顺序是：n号海盗-&gt;n-1号海盗…1号海盗，即是：先由n号海盗决定如何分配，若分配不均，n号被扔下海，n-1号海盗再决定如何分配，依次类推。在该规则下，n号海盗最佳分配方案应当如此（为简单，避免使用地板函数，按n为奇偶数分类讨论）：<br />
不妨假设ones为得到1个金币海盗数，zeros为得到0个金币的海盗数。</p>
<ol>
<li>当n为奇数时，ones=zeros=(n-1)/2，分配方案为Gold-ones,0,1…0,1</li>
<li>当n为偶数时，ones=( n-2)/2,zeros=n/2，分配方案为Gold-ones,0,1…1,0</li>
</ol>
<p>该命题从上述分析中的规律中得出，不是定理，更不是公理，作为标准化解决方案需要严格证明。</p>
<p><strong>证明：</strong><br />
注释：使用跳跃数学归纳法证明，跳跃的step为2。<br />
先证明n为奇数时命题是否成立。<br />
当n=1时，显然该命题成立<br />
假设当n=m(m&gt;1)时命题成立，则分配方案为<br />
Ones(m) = Zeros(m) = (m-1)/2<br />
Proposal(m) = Gold-Ones(m),0,1,…,0,1<br />
= Gold-(m-1)/2, 0, 1, …,0,1<br />
当n=m+1时，显然命题成立，理由如下<br />
Ones(m+1) = (m+1-2)/2=(m-1)/2，Zeros(m+1) = (m+1)/2<br />
注意：a) m+1为偶数，计算ones和zeros需要换个公式b) 对比n=m情形，仅仅是多了个0。<br />
Proposal(m+1) = Gold-Ones(m+1),0,1,…,0,1,0<br />
= Gold-(m-1)/2, 0, 1, …,0,1,0<br />
对比Ones(m),Ones(m+1),Zeros(m),Zeros(m+1)可以看出仅仅是在Proposal(m)序列后面添个0。这会导致Proposal(m+1)与Proposal(m)两个序列中，0、1交错序列刚好错位，对应金币分配方案中则为：m+1号海盗分配方案就是把Proposal(m)中没有得到金币的人每人给1个金币实现自己金币最大化，同时保证同意的人数大于等于2。<br />
综上所述，当n为奇数时，该命题成立。<br />
再证明n为偶数时命题是否成立。<br />
当n=2时，命题成立（大于的最小偶数只能是2）<br />
归纳方法同1。<br />
综合1、2分析，该命题成立。<br />
证毕。</p>
<p><strong>该标准化解决方案用程序实现如下</strong><br />
说明：该程序考虑了金币数量远小于海盗数量时，最先出来分配的部分海盗都得喂鲨鱼去了。</p>
<pre class="c">$ cat nim.c
#include 

const int g_first = 2;
const int g_zero = 0;
const int g_one = 1;

int print_proposal(int *gold, int *pirate, int *ones, int *zeros, int *status) {
        int             ret = 1;
        int             number = 0;
        int             remain = *gold - *ones;
        if (*pirate &lt;= 0) {
                printf(".\n");
                return 0;
        }
        if (remain &lt;= 0) {
                number = 0;     /* not enough gold, killed by others, regenerate proposal */
                ret = 1;        /* conitnue */

                /* regenerate proposal */
                if (*pirate % 2 == 0) {
                        *ones = (*pirate - 2) / 2;
                        *zeros = *pirate / 2;
                } else {
                        *ones = *zeros = (*pirate - 1) / 2;
                }
        } else if (*status == g_one) {
                number = 1;
                *ones--;
                *status = g_zero;
        } else if (*status == g_zero) {
                number = 0;
                *zeros--;
                *status = g_one;
        } else {
                number = remain;
                *status = g_zero;
        }
        if (*status != g_first &amp;&amp; *ones &lt;= 0 &amp;&amp; *zeros &lt;= 0) {
                ret = 0;
        }

        printf("%d ", number);
        *pirate = *pirate - 1;

        return ret;
}

int main()
{
        int             gold;
        int             pirate;
        int             ones;
        int             zeros;
        int             temp;
        int             status;         /* process first, zero or one */
        printf("Please Enter gold and pirate number:\n");
        while (scanf("%d %d", &amp;gold, &amp;pirate) == 2) {
                if (pirate &lt; 1 || gold &lt; 1)
                        break;

                if (pirate % 2 == 0) {
                        ones = (pirate - 2) / 2;
                        zeros = pirate / 2;
                } else {
                        ones = zeros = (pirate - 1) / 2;
                }

                status = g_first;
                printf("Proposal(%d, %d) is: ", gold, pirate);
                temp = pirate;
                while (print_proposal(&amp;gold, &amp;temp, &amp;ones, &amp;zeros, &amp;status))
                        ;
                if (pirate == 1)
                        printf(".\n");

                printf("\n");
                printf("Please Enter gold and pirate number:\n");
        }
        return 0;
}</pre>
<p>程序运行结果如下所示<br />
<code><br />
$ gcc nim.c -o nim<br />
$ ./nim<br />
Please Enter gold and pirate number:<br />
100 1<br />
Proposal(100, 1) is: 100 .</code></p>
<p><code>Please Enter gold and pirate number:<br />
100 2<br />
Proposal(100, 2) is: 100 0 .</code></p>
<p><code>Please Enter gold and pirate number:<br />
100 3<br />
Proposal(100, 3) is: 99 0 1 .</code></p>
<p><code>Please Enter gold and pirate number:<br />
100 4<br />
Proposal(100, 4) is: 99 0 1 0 .</code></p>
<p><code>Please Enter gold and pirate number:<br />
100 5<br />
Proposal(100, 5) is: 98 0 1 0 1 .</code></p>
<p><code> </code></p>
<p><code>Please Enter gold and pirate number:<br />
0<br />
</code></p>
<h3>决定下一步</h3>
<p>本问题到此为止，暂时没有下一步动作。</p>
<h3>总结</h3>
<p>这个结论告诉我们</p>
<ol>
<li>最先掌握分配权的人，看似最危险，胆小的人可能会担心所有人都不支持你，你就只能下海去喂鲨鱼了。其实，他优先掌握了主动权，天下武功，唯快不破，掌握市场先机很重要。</li>
<li>越快越好，但不能快过了头。100个金币，1000个海盗的话，最先出来分配的人必然死掉。同样的，20年前搞酒店搜索，率先占据主动权，快得一塌糊涂那也没戏。</li>
</ol>
<p>完。</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.losthit.com/archives/pirate-and-gold/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>单件模式：Singleton那些事</title>
		<link>http://blog.losthit.com/archives/singleton-everthing/</link>
		<comments>http://blog.losthit.com/archives/singleton-everthing/#comments</comments>
		<pubDate>Sun, 28 Feb 2010 22:56:01 +0000</pubDate>
		<dc:creator>Zealot</dc:creator>
				<category><![CDATA[C/C++]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[设计模式]]></category>
		<category><![CDATA[c++]]></category>
		<category><![CDATA[DCLP]]></category>
		<category><![CDATA[gtest]]></category>
		<category><![CDATA[pattern]]></category>
		<category><![CDATA[singleton]]></category>

		<guid isPermaLink="false">http://blog.losthit.com/?p=287</guid>
		<description><![CDATA[单件模式确保一个类只有一个实例，并提供一个全局的访问点。 &#8211;《Head First 设计模式》 有些时候，我们恰好需要这样一种设计，保证我们实例化的类在进程地址空间内只有一个实例，有了... ]]></description>
			<content:encoded><![CDATA[<blockquote><p><strong>单件模式</strong>确保一个类只有一个实例，并提供一个全局的访问点。      &#8211;《Head First 设计模式》</p></blockquote>
<p>有些时候，我们恰好需要这样一种设计，保证我们实例化的类在进程地址空间内只有一个实例，有了Singleton，一切似乎都简单明了，其实暗藏杀机。</p>
<p><strong>1. C++实现Singleton模式简单示例</strong></p>
<p>简单的C++实现示例代码</p>
<pre name="code" class="c++">
class Singleton {
    public:
        static Singleton* GetInstance(void) {
            if (Singleton::m_instance == NULL) {
                Singleton::m_instance = new Singleton();
            }
            return Singleton::m_instance;
        }
    private:
        static Singleton* m_instance;
        Singleton() {}
};
</pre>
<p>使用gtest测试，简单地测试一下每次调用GetInstance是否返回同一地址</p>
<pre name="code" class="c++">
#include <cstdlib>
#include <iostream>

#include <gtest/gtest.h>
using namespace std;
#define NEW_COUNT 4096

class Singleton {
    public:
        static Singleton* GetInstance(void) {
            if (Singleton::m_instance == NULL) {
                Singleton::m_instance = new Singleton();
            }
            return Singleton::m_instance;
        }
    private:
        static Singleton* m_instance;
        Singleton() {}
};

Singleton* Singleton::m_instance = NULL;

TEST(Singleton, sample) {
    Singleton* init_instance = Singleton::GetInstance();
    ASSERT_NE(init_instance, (Singleton*)NULL);

    Singleton* p = NULL;
    ASSERT_EQ(p, (Singleton*)NULL);

    for (int i = 0; i < NEW_COUNT; ++i) {
        p = Singleton::GetInstance();
        ASSERT_EQ(init_instance, p);
    }
}

int main(int argc, char **argv)
{
    ::testing::InitGoogleTest(&#038;argc, argv);
    return RUN_ALL_TESTS();
}
</pre>
<p>测试结果显示没有问题：<br />
<code>$ ./singleton<br />
[==========] Running 1 test from 1 test case.<br />
[----------] Global test environment set-up.<br />
[----------] 1 test from Singleton<br />
[ RUN      ] Singleton.sample<br />
[       OK ] Singleton.sample (1 ms)<br />
[----------] 1 test from Singleton (1 ms total)</code></p>
<p><code> </code></p>
<p><code>[----------] Global test environment tear-down<br />
[==========] 1 test from 1 test case ran. (2 ms total)<br />
[  PASSED  ] 1 test.</code></p>
<p>当然，这种测试没有太大意义。给出测试结果，主要用于之后的对比。</p>
<p><strong>2. python程序中调用Singleton模式的C++代码</strong><br />
初次接触Singleton后发现，使用Singleton模式的C++代码融合到python中有意想不到的惊喜：如果有某个类初始化需要很长时间，而之后调用的速度都很快的话，使用Singleton模式，然后在python中多次调用时，不会出现重复的初始化操作。<br />
简单地尝试了一下</p>
<p>首先在singleton.cpp中添加了一行输出，标识一次初始化操作：</p>
<pre name="code" class="c++">
Singleton* Singleton::GetInstance(void) {
    if (Singleton::m_instance == NULL) {
        Singleton::m_instance = new Singleton();
        std::cout << "initialize here." << std::endl;
    }
    return Singleton::m_instance;
}
</pre>
<p>封装的代码如下<br />
<code>$ cat _pysingleton.cpp -n</code></p>
<pre name="code" class="c++">
#include <Python.h>

#include "singleton.h"

using namespace std;

PyObject * GetInstance(PyObject *self, PyObject *args) {
    Singleton::GetInstance();
    return Py_BuildValue("s", NULL);
}

static PyMethodDef _pysingletonMethods[] = {
    {"GetInstance", GetInstance, METH_VARARGS, "get instance."},
    {NULL, NULL},
};

PyMODINIT_FUNC init_pysingleton(void) {
    PyObject * m;
    m = Py_InitModule("_pysingleton", _pysingletonMethods);
}
</pre>
<p>编译出来共享库_pysingleton.so<br />
<code>$ cat Makefile  -n </code></p>
<pre name="code">
CC                =       g++
FLAGS           =       -ggdb -O2 -Wall
INC               =       -I/usr/include/python2.5
LIB               =       -lgtest -lpython2.5
LLIB              =

%.o:%.cpp
        $(CC) $(FLAGS) $(INC) -c $<

_pysingleton.so: singleton.o _pysingleton.o
        $(CC) -shared $(CFLAGS) $(LLIB) $(INCLUDE) $^ -o $@

clean:
        rm -f *.so
        rm -f *.o
        rm -f *.pyc
        rm -f singleton
</pre>
<p>写个简单的python脚本测试一下在单一进程空间里，是否真的只调用一次<br />
<code>$ cat pysingleton.py -n</code></p>
<pre name="code" class="python">
#!/usr/bin/env python
# -*- coding: utf-8 -*-

''' sample for pysingleton
'''

import os
import sys
import _pysingleton

class PySingleton:
    def __init__(self):
        _pysingleton.GetInstance()

def main():
    ''' main function
    '''
    for i in xrange(3):
        PySingleton()
    print 'Done'

if __name__ == '__main__':
    main()
</pre>
<p>结果是<br />
<code> $ ./pysingleton.py<br />
initialize here.<br />
Done </code></p>
<p><strong>3. 多线程中使用Singleton模式</strong><br />
多线程里就会遇到一个double-check问题 (double-check-lock problem, DCLP)<br />
首先，静态变量m_instance作用域是全局的，处于临界区，在多线程需要加锁。这一点很好理解。<br />
但是，简单的在if外面加锁势必会影响性能，毕竟只有第一次调用才会生效，每次都有一次锁操作太费时，也没必要。<br />
于是，就会有double-check方法了，伪代码为<br />
<code>if (Singleton::m_instance == NULL)  // first check<br />
lock<br />
if (Singleton::m_instance == NULL)  // second check </code><br />
从这里可以看出，double-check有效地避免了重复锁操作问题。<br />
然而，问题还没有结束。采用double-check的话，又会引入另一个问题。在这里<br />
<code>Singleton::m_instance = new Singleton(); </code><br />
编译器可能会做个优化，首先将一个有效的内存地址返回给m_instance，然后再调用构造函数初始化。这样很有下一次double-check中首次检查通过，但是得到的内存地址指向的是一个未经初始化的类。后果怎么样，只有天知道了。<br />
更多细节，参考这里：<a href="http://www.ibm.com/developerworks/library/j-dcl.html" target="_blank">http://www.ibm.com/developerworks/library/j-dcl.html</a></p>
<p>a. 最简单的修改方法是<br />
<code>Singleton* temp = new Singleton();<br />
m_instance = temp; </code><br />
但是一个自作聪明地编译器还是会把结果优化成难以想象的样子<br />
b. 另一个方法就是使用volatile关键字，用以声明不受编译器优化的影响<br />
比如 <code>Singleton* volatile temp = new Singleton();</code><br />
但是远远不够，temp是volatile，但是*temp呢，temp-&gt;foo,temp-&gt;bar...这些成员呢？所以，要改的话，得把全世界都改成volatile，除了那个lock-_-|||</p>
<p><strong>4. 以上都只考虑单核，再考虑一下多核机器，问题将会更加复杂</strong></p>
<blockquote><p><strong>总结：珍爱生命，远离Singleton。</strong>尤其是不要把Singleton放进通用库中，还有C++中那个叫template的高级玩意儿，都搞在一起老天都很难保证会发生些什么。</p></blockquote>
<p>附<br />
1. <strong>这里也在讨论单例模式</strong>：<a href="http://code.google.com/p/google-singleton-detector/wiki/WhySingletonsAreControversial" target="_blank">Why Singletons Are Controversial</a><br />
2. 代码托管到<a href="code.google.com" target="_blank">Google Code</a>，欢迎围观、讨论、批评、挑bug：<a href="http://code.google.com/p/zldemo/source/browse/#svn/trunk/blog/singleton_everything" target="_blank">点此进入</a>（http://code.google.com/p/zldemo/source/browse/#svn/trunk/blog/singleton_everything）<br />
(墙内用户请不要使用https访问)</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.losthit.com/archives/singleton-everthing/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>C++拷贝构造函数没有执行的问题</title>
		<link>http://blog.losthit.com/archives/cpp-copy-constructor-problem/</link>
		<comments>http://blog.losthit.com/archives/cpp-copy-constructor-problem/#comments</comments>
		<pubDate>Wed, 29 Apr 2009 11:48:20 +0000</pubDate>
		<dc:creator>Zealot</dc:creator>
				<category><![CDATA[C/C++]]></category>
		<category><![CDATA[Computer Science]]></category>
		<category><![CDATA[c++]]></category>
		<category><![CDATA[constructor]]></category>
		<category><![CDATA[problem]]></category>

		<guid isPermaLink="false">http://zealot.hitidea.org/?p=89</guid>
		<description><![CDATA[问题是在这http://lilacbbs.com/forum/d.php?bid=66&#38;id=62395，想了半天想不明白 摘要就是 Fred z = Fred(3);时没有执行拷贝构造函数，查了标准手册才发现原来如此：会不会调用拷贝构造函数由具体编译器... ]]></description>
			<content:encoded><![CDATA[<p style="margin: 0in;font-family: SimSun;font-size: 10pt">问题是在这<a href="http://lilacbbs.com/forum/d.php?bid=66&amp;id=62395">http://lilacbbs.com/forum/d.php?bid=66&amp;id=62395</a>，想了半天想不明白</p>
<p style="margin: 0in;font-size: 10pt"><span style="font-family: SimSun" lang="zh-CN">摘要就是</span><span style="font-family: Calibri" lang="en-US"> Fred z = Fred(3);</span><span style="font-family: SimSun" lang="zh-CN">时没有执行拷贝构造函数，查了标准手册才发现原来如此：会不会调用拷贝构造函数由具体编译器实现决定：</span></p>
<p style="margin: 0in;font-family: SimSun;font-size: 10pt">
<p style="margin: 0in;font-family: SimSun;font-size: 10pt">Standard C++98 12.8</p>
<p style="margin: 0in;font-family: SimSun;font-size: 10pt">15 Whenever a temporary class object is copied using a copy constructor, and this object and the copy have the</p>
<p style="margin: 0in;font-family: SimSun;font-size: 10pt">same cvunqualified</p>
<p style="margin: 0in;font-family: SimSun;font-size: 10pt">type, <span style="color: red">an implementation is permitted to treat the original and the copy as two different</span></p>
<p style="margin: 0in;font-family: SimSun;font-size: 10pt;color: red">ways of referring to the same object and not perform a copy at all, even if the class copy constructor or</p>
<p style="margin: 0in;font-family: SimSun;font-size: 10pt"><span style="color: red">destructor have side effects.</span> For a function with a class return type, if the expression in the return statement</p>
<p style="margin: 0in;font-family: SimSun;font-size: 10pt">is the name of a local object, and the cvunqualified</p>
<p style="margin: 0in;font-family: SimSun;font-size: 10pt">type of the local object is the same as the function</p>
<p style="margin: 0in;font-family: SimSun;font-size: 10pt">return type, an implementation is permitted to omit creating the temporary object to hold the function return</p>
<p style="margin: 0in;font-family: SimSun;font-size: 10pt">value, even if the class copy constructor or destructor has side effects. In these cases, the object is</p>
<p style="margin: 0in;font-family: SimSun;font-size: 10pt">destroyed at the later of times when the original and the copy would have been destroyed without the optimization.</p>
<p style="margin: 0in;font-family: SimSun;font-size: 10pt">111) [Example:</p>
<p style="margin: 0in;font-family: SimSun;font-size: 10pt">class Thing {</p>
<p style="margin: 0in;font-family: SimSun;font-size: 10pt">public:</p>
<p style="margin: 0in;font-family: SimSun;font-size: 10pt">Thing();</p>
<p style="margin: 0in;font-family: SimSun;font-size: 10pt">~Thing();</p>
<p style="margin: 0in;font-family: SimSun;font-size: 10pt">Thing(const Thing&amp;);</p>
<p style="margin: 0in;font-family: SimSun;font-size: 10pt">Thing operator=(const Thing&amp;);</p>
<p style="margin: 0in;font-family: SimSun;font-size: 10pt">void fun();</p>
<p style="margin: 0in;font-family: SimSun;font-size: 10pt">};</p>
<p style="margin: 0in;font-family: SimSun;font-size: 10pt">Thing f() {</p>
<p style="margin: 0in;font-family: SimSun;font-size: 10pt">Thing t;</p>
<p style="margin: 0in;font-family: SimSun;font-size: 10pt">return t;</p>
<p style="margin: 0in;font-family: SimSun;font-size: 10pt">}</p>
<p style="margin: 0in;font-family: SimSun;font-size: 10pt">Thing t2 = f();</p>
<p style="margin: 0in;font-family: SimSun;font-size: 10pt">Here t does not need to be copied when returning from f. The return value of f may be constructed</p>
<p style="margin: 0in;font-family: SimSun;font-size: 10pt">directly into the object t2. ]</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.losthit.com/archives/cpp-copy-constructor-problem/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>C++解析json的parser，tinyjson问题的解决办法</title>
		<link>http://blog.losthit.com/archives/tinyjson-cpp-json-parser/</link>
		<comments>http://blog.losthit.com/archives/tinyjson-cpp-json-parser/#comments</comments>
		<pubDate>Sat, 25 Apr 2009 17:37:42 +0000</pubDate>
		<dc:creator>Zealot</dc:creator>
				<category><![CDATA[C/C++]]></category>
		<category><![CDATA[Computer Science]]></category>
		<category><![CDATA[bug]]></category>
		<category><![CDATA[c++]]></category>
		<category><![CDATA[parser]]></category>
		<category><![CDATA[tinyjson]]></category>
		<category><![CDATA[编译]]></category>

		<guid isPermaLink="false">http://zealot.hitidea.org/?p=67</guid>
		<description><![CDATA[解决C++中tinyjson解析json的bug，简单修改了tinyjson的parser... ]]></description>
			<content:encoded><![CDATA[<p style="margin: 0in;font-size: 10pt"><span style="font-family: SimSun">前不久需要解析一个</span><span style="font-family: Calibri">json</span><span style="font-family: SimSun">的接口，上</span><span style="font-family: Calibri">json</span><span style="font-family: SimSun">官网（</span><a href="http://www.json.org/json-zh.html"><span style="font-family: SimSun">http://www.json.org/json-zh.html</span></a><span style="font-family: SimSun">）上找找</span><span style="font-family: Calibri">C++</span><span style="font-family: SimSun">的</span><span style="font-family: Calibri">parser</span><span style="font-family: SimSun">。结果发现长长的</span><span style="font-family: Calibri">list</span><span style="font-family: SimSun">，支持各种语言的各种版本。上第一个官网看看（</span><a href="http://blog.beef.de/projects/tinyjson/"><span style="font-family: SimSun">http://blog.beef.de/projects/tinyjson/</span></a><span style="font-family: SimSun">），对</span><span style="font-family: Calibri">tiny**</span><span style="font-family: SimSun">的东西还是比较感兴趣的，比如</span><span style="font-family: Calibri">tinyxml</span><span style="font-family: SimSun">。。。</span></p>
<p style="margin: 0in;font-size: 10pt"><span style="font-family: SimSun">果然够</span><span style="font-family: Calibri">tiny</span><span style="font-family: SimSun">，下载下来一看发现只有一个</span><span style="font-family: Calibri">.hpp</span><span style="font-family: SimSun">文件就行了。接下来就开始</span><span style="font-family: Calibri">ft</span><span style="font-family: SimSun">了，按照官网上的</span><span style="font-family: Calibri">sample</span><span style="font-family: SimSun">调用了一下，编译都不过：</span></p>
<p style="margin: 0in;font-family: SimSun;font-size: 10pt"><span> </span>../include/tinyjson/tinyjson.hpp: In function &#8216;typename json::grammar&lt;typename Iterator::value_type&gt;::variant json::parse(const Iterator&amp;, const Iterator&amp;)&#8217;:</p>
<p style="margin: 0in;font-family: SimSun;font-size: 10pt">../include/tinyjson/tinyjson.hpp:549: error: expected `;&#8217; before &#8216;st&#8217;</p>
<p style="margin: 0in;font-family: SimSun;font-size: 10pt">../include/tinyjson/tinyjson.hpp:550: error: &#8216;st&#8217; was not declared in this scope</p>
<p style="margin: 0in;font-family: SimSun;font-size: 10pt">../include/tinyjson/tinyjson.hpp: In function &#8216;typename json::grammar&lt;typename Iterator::value_type&gt;::variant json::parse(const Iterator&amp;, const Iterator&amp;) [with Iterator = __gnu_cxx::__normal_iterator&lt;char*, std::basic_string&lt;char, std::char_traits&lt;char&gt;, std::allocator&lt;char&gt; &gt; &gt;]&#8216;:</p>
<p style="margin: 0in;font-family: SimSun;font-size: 10pt">test.cpp:45:<span> </span>instantiated from here</p>
<p style="margin: 0in;font-family: SimSun;font-size: 10pt">../include/tinyjson/tinyjson.hpp:549: error: dependent-name &#8216;json::grammar&lt;typename Iterator::value_type&gt;::stack&#8217; is parsed as a non-type, but instantiation yields a type</p>
<p style="margin: 0in;font-family: SimSun;font-size: 10pt">../include/tinyjson/tinyjson.hpp:549: note: say &#8216;typename json::grammar&lt;typename Iterator::value_type&gt;::stack&#8217; if a type is meant</p>
<p style="margin: 0in;font-family: SimSun;font-size: 10pt">……</p>
<p style="margin: 0in;font-size: 10pt"><span style="font-family: Calibri">google</span><span style="font-family: SimSun">了一下，相关资料真少，难道用</span><span style="font-family: Calibri">c++</span><span style="font-family: SimSun">解析</span><span style="font-family: Calibri">json</span><span style="font-family: SimSun">很发指么，最后硬着头皮在这个日文的</span><span style="font-family: Calibri">blog</span><span style="font-family: SimSun">（</span><a href="http://d.hatena.ne.jp/S_Nakayama/20081207/1228592806"><span style="font-family: SimSun">http://d.hatena.ne.jp/S_Nakayama/20081207/1228592806</span></a><span style="font-family: SimSun">）上找到了答案。修改记录如下：</span></p>
<p style="margin: 0in;font-family: SimSun;font-size: 10pt">549c549</p>
<p style="margin: 0in;font-family: SimSun;font-size: 10pt">&lt;<span> </span>json::grammar&lt; typename Iterator::value_type &gt;::stack st;</p>
<p style="margin: 0in;font-family: SimSun;font-size: 10pt">&#8212;</p>
<p style="margin: 0in;font-family: SimSun;font-size: 10pt">&gt;<span> </span>typename json::grammar&lt; typename Iterator::value_type &gt;::stack st;</p>
<p style="margin: 0in;font-family: SimSun;font-size: 10pt">565c565</p>
<p style="margin: 0in;font-family: SimSun;font-size: 10pt">&lt;<span> </span>return json::grammar&lt; typename Iterator::value_type &gt;::variant(new boost::any());</p>
<p style="margin: 0in;font-family: SimSun;font-size: 10pt">&#8212;</p>
<p style="margin: 0in;font-family: SimSun;font-size: 10pt">&gt;<span> </span>return typename json::grammar&lt; typename Iterator::value_type &gt;::variant(new boost::any());</p>
<p style="margin: 0in;font-size: 10pt"><span style="font-family: SimSun">相应的加上</span><span style="font-family: Calibri">typename</span><span style="font-family: SimSun">就行了。</span></p>
<p style="margin: 0in;font-size: 10pt"><span style="font-family: SimSun">最后，还想说一句，</span><span style="font-family: Calibri">tinyjson</span><span style="font-family: SimSun">官网的</span><span style="font-family: Calibri">sample</span><span style="font-family: SimSun">里遍历的方法也没编译过，最后改了一下遍历函数的参数，函数原型是void Traverse(json::grammar&lt;char&gt;::variant const v, const string&amp; name, int level)。</span><span style="font-family: Calibri">name</span><span style="font-family: SimSun">表示上级节点名称，</span><span style="font-family: Calibri">level</span><span style="font-family: SimSun">表示当前内容的深度。虽然看着还是不爽，但好歹能工作了。</span></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.losthit.com/archives/tinyjson-cpp-json-parser/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

