﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客-qiezi的学习园地-随笔分类-C＋＋</title><link>http://www.cppblog.com/cpunion/category/49.html</link><description>AS/C/C++/D/Java/JS/Python/Ruby</description><language>zh-cn</language><lastBuildDate>Tue, 20 May 2008 02:40:29 GMT</lastBuildDate><pubDate>Tue, 20 May 2008 02:40:29 GMT</pubDate><ttl>60</ttl><item><title>泛型矩阵类</title><link>http://www.cppblog.com/cpunion/archive/2006/04/13/5464.html</link><dc:creator>qiezi</dc:creator><author>qiezi</author><pubDate>Thu, 13 Apr 2006 05:52:00 GMT</pubDate><guid>http://www.cppblog.com/cpunion/archive/2006/04/13/5464.html</guid><wfw:comment>http://www.cppblog.com/cpunion/comments/5464.html</wfw:comment><comments>http://www.cppblog.com/cpunion/archive/2006/04/13/5464.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/cpunion/comments/commentRss/5464.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/cpunion/services/trackbacks/5464.html</trackback:ping><description><![CDATA[<p>
		</p>
		<p>矩阵就不用再解释了，写成泛型主要是为了几个方便：<br />1、方便在栈上分配空间。由于维度在编译期已知，所以可以做到在栈上分配空间。当然如果这个对象是new出来的，自然是在堆上分配，这里说的是在栈上分配这个对象时，矩阵元素所占用的空间也在栈上分配。<br />2、方便在编译期检查非法的矩阵运算。C++模板的强大推导能力可以在编译期推导出结果矩阵的维度。<br />3、泛型类在方法内联上具有优势。<br /><br />这个矩阵类为了能够直接从数组赋值，使用了一个ArrayPorxy类（可参考《Imperfect C++》）。<br /><br />代码如下：<br /><br /></p>
		<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee">
				<span style="COLOR: #000000">template </span>
				<span style="COLOR: #000000">&lt;</span>
				<span style="COLOR: #0000ff">class</span>
				<span style="COLOR: #000000"> T, </span>
				<span style="COLOR: #0000ff">int</span>
				<span style="COLOR: #000000"> D1, </span>
				<span style="COLOR: #0000ff">int</span>
				<span style="COLOR: #000000"> D2</span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #000000">1</span>
				<span style="COLOR: #000000">&gt;</span>
				<span style="COLOR: #000000">
						<br />
				</span>
				<span style="COLOR: #0000ff">class</span>
				<span style="COLOR: #000000"> ArrayProxy<br />{<br />    T</span>
				<span style="COLOR: #000000">*</span>
				<span style="COLOR: #000000"> data;<br /></span>
				<span style="COLOR: #0000ff">public</span>
				<span style="COLOR: #000000">:<br />    ArrayProxy(T (</span>
				<span style="COLOR: #000000">&amp;</span>
				<span style="COLOR: #000000">value)[D1][D2])<br />        : data(</span>
				<span style="COLOR: #000000">&amp;</span>
				<span style="COLOR: #000000">value[</span>
				<span style="COLOR: #000000">0</span>
				<span style="COLOR: #000000">][</span>
				<span style="COLOR: #000000">0</span>
				<span style="COLOR: #000000">])<br />    {<br />    }<br /><br />    ArrayProxy(T (</span>
				<span style="COLOR: #000000">&amp;</span>
				<span style="COLOR: #000000">value)[D1</span>
				<span style="COLOR: #000000">*</span>
				<span style="COLOR: #000000">D2])<br />        : data(value)<br />    {<br />    }<br /><br />    T</span>
				<span style="COLOR: #000000">*</span>
				<span style="COLOR: #000000"> getData() </span>
				<span style="COLOR: #0000ff">const</span>
				<span style="COLOR: #000000">
						<br />    {<br />        </span>
				<span style="COLOR: #0000ff">return</span>
				<span style="COLOR: #000000"> data;<br />    }<br />};</span>
		</div>
		<br />这个只是简单的实现。<br /><br />因为我基本上不使用这个矩阵类，所以只完成几个简单功能：<br />1、从数组赋值：<br />int a[][3] = {{1,2,3}, {4,5,6}};<br />Matrix&lt;int, 2, 3&gt; m1(a);<br />或<br />int a[] = {1,2,3, 4,5,6};<br />Matrix&lt;int, 2, 3&gt; m1(a);<br />Matrix&lt;int, 3, 2&gt; m2(a);<br />Matrix&lt;int, 6, 1&gt; m3(a);<br />Matrix&lt;int, 1, 6&gt; m4(a);<br /><br />2、矩阵乘法：<br />Matrix&lt;int, 2, 3&gt; m1;<br />Matrix&lt;int, 2, 4&gt; m2;<br />// m1 * m2  &lt;== 编译错误，维度不匹配<br />Matrix&lt;int, 3, 5&gt; m3;<br />Matrix&lt;int, 2, 5&gt; m4 = m1 * m3; // &lt;== 合法<br />// m3 * m1; // &lt;== 编译错误，维度不匹配<br /><br />源码如下：<br /><br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #000000">template </span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000"> T, </span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> R, </span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> C</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br /></span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000"> Matrix<br />{<br />    T matrix[R][C];<br /><br /></span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">:<br />    </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> Big three<img src="http://www.cppblog.com/images/dot.gif" /></span><span style="COLOR: #008000"><br /></span><span style="COLOR: #000000">    Matrix(</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">)<br />    {<br />        memset(matrix, </span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">, </span><span style="COLOR: #0000ff">sizeof</span><span style="COLOR: #000000">(matrix));<br />    }<br /><br />    Matrix(</span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000"> Matrix</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000"> rhs)<br />    {<br />        memcpy(matrix, rhs.matrix, </span><span style="COLOR: #0000ff">sizeof</span><span style="COLOR: #000000">(matrix));<br />    }<br /><br />    Matrix</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">operator</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">(</span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000"> Matrix</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000"> rhs)<br />    {<br />        memcpy(matrix, rhs.matrix, </span><span style="COLOR: #0000ff">sizeof</span><span style="COLOR: #000000">(matrix));<br />        </span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">*</span><span style="COLOR: #0000ff">this</span><span style="COLOR: #000000">;<br />    }<br /><br /></span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">:<br />    Matrix(</span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000"> ArrayProxy</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">T,R,C</span><span style="COLOR: #000000">&gt;&amp;</span><span style="COLOR: #000000"> arr)<br />    {<br />        memcpy(matrix, arr.getData(), </span><span style="COLOR: #0000ff">sizeof</span><span style="COLOR: #000000">(matrix));<br />    }<br /><br />    </span><span style="COLOR: #000000">~</span><span style="COLOR: #000000">Matrix(</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">)<br />    {<br />    }<br /><br /></span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">:<br />    T </span><span style="COLOR: #0000ff">get</span><span style="COLOR: #000000">(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> r, </span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> c) </span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000"><br />    {<br />        assert(c </span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000"> C </span><span style="COLOR: #000000">&amp;&amp;</span><span style="COLOR: #000000"> c </span><span style="COLOR: #000000">&gt;=</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">0</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">&amp;&amp;</span><span style="COLOR: #000000"> r </span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000"> R </span><span style="COLOR: #000000">&amp;&amp;</span><span style="COLOR: #000000"> r </span><span style="COLOR: #000000">&gt;=</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">);<br />        </span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"> matrix[r][c];<br />    }<br /><br />    </span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">set</span><span style="COLOR: #000000">(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> r, </span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> c, T v)<br />    {<br />        assert(c </span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000"> C </span><span style="COLOR: #000000">&amp;&amp;</span><span style="COLOR: #000000"> c </span><span style="COLOR: #000000">&gt;=</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">0</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">&amp;&amp;</span><span style="COLOR: #000000"> r </span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000"> R </span><span style="COLOR: #000000">&amp;&amp;</span><span style="COLOR: #000000"> r </span><span style="COLOR: #000000">&gt;=</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">);<br />        matrix[r][c] </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> v;<br />    }<br /><br />    </span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> getCols () </span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000"><br />    {<br />        </span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"> C;<br />    }<br /><br />    </span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> getRows () </span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000"><br />    {<br />        </span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"> R;<br />    }<br /><br />    </span><span style="COLOR: #0000ff">bool</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">operator</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">==</span><span style="COLOR: #000000"> (</span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000"> Matrix</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000"> rhs) <span style="COLOR: #0000ff">const</span><br />    {<br />        </span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"> memcmp(matrix, rhs.matrix, </span><span style="COLOR: #0000ff">sizeof</span><span style="COLOR: #000000">(matrix)) </span><span style="COLOR: #000000">==</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;<br />    }<br /><br />    </span><span style="COLOR: #0000ff">bool</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">operator</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">!=</span><span style="COLOR: #000000"> (</span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000"> Matrix</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000"> rhs) <span style="COLOR: #0000ff">const</span><br />    {<br />        </span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">!</span><span style="COLOR: #000000">(</span><span style="COLOR: #000000">*</span><span style="COLOR: #0000ff">this</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">==</span><span style="COLOR: #000000"> rhs);<br />    }<br />};<br /><br />template </span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000"> T, </span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> R, </span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> C, </span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> C1</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br />Matrix</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">T,R,C1</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">operator</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000"> (</span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000"> Matrix</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">T,R,C</span><span style="COLOR: #000000">&gt;&amp;</span><span style="COLOR: #000000"> lhs, </span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000"> Matrix</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">T,C,C1</span><span style="COLOR: #000000">&gt;&amp;</span><span style="COLOR: #000000"> rhs)<br />{<br />    Matrix</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">T,R,C1</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"> result;<br />    </span><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000"> (</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> r</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">; r</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">R; </span><span style="COLOR: #000000">++</span><span style="COLOR: #000000">r)<br />    {<br />        </span><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000"> (</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> c</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">; c</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">C1; </span><span style="COLOR: #000000">++</span><span style="COLOR: #000000">c)<br />        {<br />            </span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> value </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;<br />            </span><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000"> (</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> i</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">; i</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">C; </span><span style="COLOR: #000000">++</span><span style="COLOR: #000000">i)<br />            {<br />                value </span><span style="COLOR: #000000">+=</span><span style="COLOR: #000000"> lhs.</span><span style="COLOR: #0000ff">get</span><span style="COLOR: #000000">(r,i) </span><span style="COLOR: #000000">*</span><span style="COLOR: #000000"> rhs.</span><span style="COLOR: #0000ff">get</span><span style="COLOR: #000000">(i,c);<br />            }<br />            result.</span><span style="COLOR: #0000ff">set</span><span style="COLOR: #000000">(r,c,value);<br />        }<br />    }<br />    </span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"> result;<br />}</span></div><br />测试代码：<br /><br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> main()<br />{<br />    {<br />        </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> 测试初始化</span><span style="COLOR: #008000"><br /></span><span style="COLOR: #000000">        Matrix</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">, </span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">, </span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"> m1;<br />        Matrix</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">, </span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">, </span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"> m2(m1);<br />        Matrix</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">, </span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">, </span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"> m3 </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> m1;<br />        Matrix</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">, </span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">, </span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"> m4;<br />        m4 </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> m1;<br /><br />        </span><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000"> (</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> i</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">; i</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">; i</span><span style="COLOR: #000000">++</span><span style="COLOR: #000000">)<br />            </span><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000"> (</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> j</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">; j</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">; j</span><span style="COLOR: #000000">++</span><span style="COLOR: #000000">)<br />            {<br />                assert (m1.</span><span style="COLOR: #0000ff">get</span><span style="COLOR: #000000">(i, j) </span><span style="COLOR: #000000">==</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">);<br />                assert (m2.</span><span style="COLOR: #0000ff">get</span><span style="COLOR: #000000">(i, j) </span><span style="COLOR: #000000">==</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">);<br />                assert (m3.</span><span style="COLOR: #0000ff">get</span><span style="COLOR: #000000">(i, j) </span><span style="COLOR: #000000">==</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">);<br />                assert (m4.</span><span style="COLOR: #0000ff">get</span><span style="COLOR: #000000">(i, j) </span><span style="COLOR: #000000">==</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">);<br />            }<br /><br />        </span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> a[] </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> {</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">, </span><span style="COLOR: #000000">5</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">6</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">7</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">8</span><span style="COLOR: #000000">, </span><span style="COLOR: #000000">9</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">10</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">11</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">12</span><span style="COLOR: #000000">};<br />        Matrix</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">, </span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">, </span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"> m5(a);<br /><br />        </span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> b[</span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">][</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">] </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> { {</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">},<br />                        {</span><span style="COLOR: #000000">5</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">6</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">7</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">8</span><span style="COLOR: #000000">},<br />                        {</span><span style="COLOR: #000000">9</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">10</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">11</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">12</span><span style="COLOR: #000000">}};<br /><br />        Matrix</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">, </span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">, </span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"> m6(b);<br /><br />        Matrix</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">, </span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">, </span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"> m7(m5);<br />        Matrix</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">, </span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">, </span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"> m8 </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> m5;<br />        Matrix</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">, </span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">, </span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"> m9;<br />        m9 </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> m5;<br /><br />        </span><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000"> (</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> i</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">; i</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">; i</span><span style="COLOR: #000000">++</span><span style="COLOR: #000000">)<br />            </span><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000"> (</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> j</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">; j</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">; j</span><span style="COLOR: #000000">++</span><span style="COLOR: #000000">)<br />            {<br />                assert (m5.</span><span style="COLOR: #0000ff">get</span><span style="COLOR: #000000">(i, j) </span><span style="COLOR: #000000">==</span><span style="COLOR: #000000"> i</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">j</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">);<br />                assert (m6.</span><span style="COLOR: #0000ff">get</span><span style="COLOR: #000000">(i, j) </span><span style="COLOR: #000000">==</span><span style="COLOR: #000000"> i</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">j</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">);<br />                assert (m7.</span><span style="COLOR: #0000ff">get</span><span style="COLOR: #000000">(i, j) </span><span style="COLOR: #000000">==</span><span style="COLOR: #000000"> i</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">j</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">);<br />                assert (m8.</span><span style="COLOR: #0000ff">get</span><span style="COLOR: #000000">(i, j) </span><span style="COLOR: #000000">==</span><span style="COLOR: #000000"> i</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">j</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">);<br />                assert (m9.</span><span style="COLOR: #0000ff">get</span><span style="COLOR: #000000">(i, j) </span><span style="COLOR: #000000">==</span><span style="COLOR: #000000"> i</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">j</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">);<br />            }<br /><br />        </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> 维数不匹配，编译错误<br />        </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> Matrix&lt;int, 4, 5&gt; m10 = m9;</span><span style="COLOR: #008000"><br /></span><span style="COLOR: #000000">        </span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> c[][</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">] </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> {{</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">}, {</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">}};<br />        </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> 数组大小不匹配，编译错误<br />        </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">Matrix&lt;int, 3, 4&gt; m10(c);</span><span style="COLOR: #008000"><br /></span><span style="COLOR: #000000">        </span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> d[] </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> {</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">};<br />        </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> 数组大小不匹配，编译错误<br />        </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">Matrix&lt;int, 3, 4&gt; m11(d);<br /><br />        </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> 乘法维数不合适，无法相乘<br />        </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">m1 * m2;</span><span style="COLOR: #008000"><br /></span><span style="COLOR: #000000"><br />        Matrix</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"> m12;<br />        </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> 匹配，可以相乘</span><span style="COLOR: #008000"><br /></span><span style="COLOR: #000000">        Matrix</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">, </span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">, </span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"> m13 </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> m1 </span><span style="COLOR: #000000">*</span><span style="COLOR: #000000"> m12;<br /><br />        Matrix</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">, </span><span style="COLOR: #000000">8</span><span style="COLOR: #000000">, </span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"> m14;<br />        </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> 无法相乘<br />        </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">Matrix&lt;int, 3, 3&gt; m15 = m1 * m14;<br />        </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> 可以相乘</span><span style="COLOR: #008000"><br /></span><span style="COLOR: #000000">        Matrix</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">, </span><span style="COLOR: #000000">8</span><span style="COLOR: #000000">, </span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"> m15 </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> m14 </span><span style="COLOR: #000000">*</span><span style="COLOR: #000000"> m1;<br />    }<br /><br />    {<br />        </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> 检查点乘</span><span style="COLOR: #008000"><br /></span><span style="COLOR: #000000">        </span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> a[</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">][</span><span style="COLOR: #000000">5</span><span style="COLOR: #000000">] </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> {{</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">5</span><span style="COLOR: #000000">}, {</span><span style="COLOR: #000000">6</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">7</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">8</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">9</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">10</span><span style="COLOR: #000000">}};<br />        Matrix</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">, </span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">, </span><span style="COLOR: #000000">5</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"> m1(a);<br /><br />        </span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> b[</span><span style="COLOR: #000000">5</span><span style="COLOR: #000000">][</span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">] </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> {{</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">}, {</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">5</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">6</span><span style="COLOR: #000000">}, {</span><span style="COLOR: #000000">7</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">8</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">9</span><span style="COLOR: #000000">}, {</span><span style="COLOR: #000000">10</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">11</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">12</span><span style="COLOR: #000000">}, {</span><span style="COLOR: #000000">13</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">14</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">15</span><span style="COLOR: #000000">}};<br />        Matrix</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">, </span><span style="COLOR: #000000">5</span><span style="COLOR: #000000">, </span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"> m2(b);<br /><br />        </span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> c[</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">][</span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">] </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> {{</span><span style="COLOR: #000000">135</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">150</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">165</span><span style="COLOR: #000000">}, {</span><span style="COLOR: #000000">310</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">350</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">390</span><span style="COLOR: #000000">}};<br />        Matrix</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">, </span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">, </span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"> m3(c);<br /><br />        Matrix</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">, </span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">, </span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"> m4 </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> m1 </span><span style="COLOR: #000000">*</span><span style="COLOR: #000000"> m2;<br />        assert(m4 </span><span style="COLOR: #000000">==</span><span style="COLOR: #000000"> m3);<br /><br />        cout </span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000"> m4.</span><span style="COLOR: #0000ff">get</span><span style="COLOR: #000000">(</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">) </span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000"> endl;<br />    }<br /><br />    </span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;<br />}</span></div><br />补充：<br />1、加法、减法只需要2个矩阵维度相同即可。 
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #000000">template </span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000"> T, </span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000"> R, </span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000"> C</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br />Matrix</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">T,R,C</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">operator</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000"> (</span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000"> Matrix</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">T,R,C</span><span style="COLOR: #000000">&gt;&amp;</span><span style="COLOR: #000000"> lhs, </span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000"> Matrix</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">T,R,C</span><span style="COLOR: #000000">&gt;&amp;</span><span style="COLOR: #000000"> rhs)<br />{<br />   </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> <img src="http://www.cppblog.com/images/dot.gif" /></span><span style="COLOR: #008000"><br /></span><span style="COLOR: #000000">}</span></div><br />2、由于1x1的矩阵可以看成一个标量，矩阵与标量运算结果维数与原矩阵相同，可以重载来实现。<br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #000000">template </span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000"> T, </span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000"> R, </span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000"> C</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br />Matrix</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">T,R,C</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">operator</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000"> (</span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000"> Matrix</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">T,R,C</span><span style="COLOR: #000000">&gt;&amp;</span><span style="COLOR: #000000"> lhs, </span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000"> Matrix&lt;T,1,1&gt;</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000"> rhs)<br />{<br />    </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> <img src="http://www.cppblog.com/images/dot.gif" /></span><span style="COLOR: #008000"><br /></span><span style="COLOR: #000000">}</span></div><br />3、由于类型泛化，可能某些合理的运算无法进行，比如float型矩阵，与一个int型标量运算等。这些最好是借助类型萃取等手段，推导出运算以后的类型。（c++0x中包含自动获取运算结果类型的关键字typeof，等几年就可以用了:)。GCC编译器中已有实现，不过似乎有BUG）。<br /><br />4、其它。泛型实现可能会有一些考虑不周的地方，强类型有强类型的好处，不过必须要有完整的泛型算法支撑，否则难以使用。也可以把泛型矩阵类从一个普通矩阵类派生，这样更容易写出通用算法，不过在实现上可能要借助于运行期多态，对于矩阵类来说并不合适。<br /><br />5、其它。。前面说C＋＋的模板相当强大，D语言模板到目前为止似乎已经完全实现了C＋＋模板的功能，还增加了一些比如字符串值参模板等特性，比C＋＋模板功能更多。在代码编写上，由于可以编写静态判断语句（编译期）以及静态断言，编写模板比C＋＋更容易。有时间可以试试用它写个矩阵类，纯粹是兴趣，这些东西真的很难用到，现成的库也挺多。<br /><br />6、其它。。。c++0x要提供“template typedef”，也就是可以这样定义：<br />template &lt;int R, int C&gt; typedef Matrix&lt;int, R, C&gt; MatrixInt;  // 定义类型，维度不定<br />template &lt;class T&gt; typedef Matrix&lt;T, 4, 4&gt; Matrix4x4; // 定义维度，类型不定<br />由此可以出定义行向量、列向量、标量等，当然实际使用起来可能没那么舒服了。<img src ="http://www.cppblog.com/cpunion/aggbug/5464.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cpunion/" target="_blank">qiezi</a> 2006-04-13 13:52 <a href="http://www.cppblog.com/cpunion/archive/2006/04/13/5464.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C＋＋/D/Python性能比较续</title><link>http://www.cppblog.com/cpunion/archive/2006/04/03/4932.html</link><dc:creator>qiezi</dc:creator><author>qiezi</author><pubDate>Mon, 03 Apr 2006 03:00:00 GMT</pubDate><guid>http://www.cppblog.com/cpunion/archive/2006/04/03/4932.html</guid><wfw:comment>http://www.cppblog.com/cpunion/comments/4932.html</wfw:comment><comments>http://www.cppblog.com/cpunion/archive/2006/04/03/4932.html#Feedback</comments><slash:comments>27</slash:comments><wfw:commentRss>http://www.cppblog.com/cpunion/comments/commentRss/4932.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/cpunion/services/trackbacks/4932.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 周末抽空做了点小测试，根据http://blog.vckbase.com/jzhang/archive/2006/03/28/18807.html中m网友修改的算法，python版本中读取所有行以后就做一个排序，再去除重复项。这个算法在我的机器上执行时间是1735ms左右，属于python版本中最快的一个。D版本暂还没想到有更优化的做法，D在处理以char[]作key的关联数组时，判断方法是先判断...&nbsp;&nbsp;<a href='http://www.cppblog.com/cpunion/archive/2006/04/03/4932.html'>阅读全文</a><img src ="http://www.cppblog.com/cpunion/aggbug/4932.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cpunion/" target="_blank">qiezi</a> 2006-04-03 11:00 <a href="http://www.cppblog.com/cpunion/archive/2006/04/03/4932.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>ABI Specifications 相关链接</title><link>http://www.cppblog.com/cpunion/archive/2006/03/23/4493.html</link><dc:creator>qiezi</dc:creator><author>qiezi</author><pubDate>Thu, 23 Mar 2006 08:08:00 GMT</pubDate><guid>http://www.cppblog.com/cpunion/archive/2006/03/23/4493.html</guid><wfw:comment>http://www.cppblog.com/cpunion/comments/4493.html</wfw:comment><comments>http://www.cppblog.com/cpunion/archive/2006/03/23/4493.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/cpunion/comments/commentRss/4493.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/cpunion/services/trackbacks/4493.html</trackback:ping><description><![CDATA[Itanium C++ ABI ($Revision: 1.86 $)<br />http://www.codesourcery.com/cxx-abi/abi.html<br /><br />C++ ABI Summary<br />http://www.codesourcery.com/cxx-abi/<br /><br />C++ ABI for IA-64: Code and Implementation Examples<br />http://www.codesourcery.com/cxx-abi/abi-examples.html<br /><br />C++ Vtable Example<br />http://www.codesourcery.com/cxx-abi/cxx-vtable-ex.html<br /><br /><br /><br />
Intel® Itanium® Processor-specific Application Binary Interface (ABI)<br />
http://developer.intel.com/design/itanium/downloads/245370.htm<br /><img src ="http://www.cppblog.com/cpunion/aggbug/4493.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cpunion/" target="_blank">qiezi</a> 2006-03-23 16:08 <a href="http://www.cppblog.com/cpunion/archive/2006/03/23/4493.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>sizeof，数组类型</title><link>http://www.cppblog.com/cpunion/archive/2006/03/22/4455.html</link><dc:creator>qiezi</dc:creator><author>qiezi</author><pubDate>Wed, 22 Mar 2006 05:04:00 GMT</pubDate><guid>http://www.cppblog.com/cpunion/archive/2006/03/22/4455.html</guid><wfw:comment>http://www.cppblog.com/cpunion/comments/4455.html</wfw:comment><comments>http://www.cppblog.com/cpunion/archive/2006/03/22/4455.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.cppblog.com/cpunion/comments/commentRss/4455.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/cpunion/services/trackbacks/4455.html</trackback:ping><description><![CDATA[sizeof('a') 在C++里面是1，C里面是4。<br /><br />C里面字符常量、enum作整数常量对待，所以是sizeof('a')大小是4。<br /><br />C99标准6.6.6有说明。<br /><br />int a = 'a'; sizeof(a)大小是1。<br /><br />另：sizeof(x)用于对类型取大小，对表达式取大小应使用sizeof x;虽然编译器没给你报错。<br /><br /><br /><br />"aaa"的类型是char[4]，"aa"的类型是char[3]，这是数组类型，数组类型作为值传递时退化为指针类型，与函数类型相似(注)。<br /><br />注：void(int)是函数类型，void(*)(int)是函数指针类型，把函数作为值传递时，退化为函数指针类型。<br /><br /><br /><br /><br /><img src ="http://www.cppblog.com/cpunion/aggbug/4455.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cpunion/" target="_blank">qiezi</a> 2006-03-22 13:04 <a href="http://www.cppblog.com/cpunion/archive/2006/03/22/4455.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>［C++之AOP］Aspect C++生成远程调用代码可能性探讨</title><link>http://www.cppblog.com/cpunion/archive/2005/12/19/1888.html</link><dc:creator>qiezi</dc:creator><author>qiezi</author><pubDate>Mon, 19 Dec 2005 14:50:00 GMT</pubDate><guid>http://www.cppblog.com/cpunion/archive/2005/12/19/1888.html</guid><wfw:comment>http://www.cppblog.com/cpunion/comments/1888.html</wfw:comment><comments>http://www.cppblog.com/cpunion/archive/2005/12/19/1888.html#Feedback</comments><slash:comments>9</slash:comments><wfw:commentRss>http://www.cppblog.com/cpunion/comments/commentRss/1888.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/cpunion/services/trackbacks/1888.html</trackback:ping><description><![CDATA[C++ 0x keynote（以下简称0x）中描述了这样一个看起来不错的东西：<BR><BR>1、本地调用代码： <PRE style="BACKGROUND: #e6e6e6"><I><FONT color=#008000>// use local object: 
</FONT></I>X x<B><FONT color=#646464>;</FONT></B> 
A a<B><FONT color=#646464>;</FONT></B> 
std<B><FONT color=#646464>::</FONT></B>string s<B><FONT color=#646464>(</FONT></B><FONT color=#ff00ff>"abc"</FONT><B><FONT color=#646464>);</FONT></B><I><FONT color=#008000> 
// … 
</FONT></I>x<B><FONT color=#646464>.</FONT></B>f<B><FONT color=#646464>(</FONT></B>a<B><FONT color=#646464>,</FONT></B> s<B><FONT color=#646464>);</FONT></B> 
</PRE>2、使用远程代理wrapper层： <PRE style="BACKGROUND: #e6e6e6"><I><FONT color=#008000>// use remote object : 
</FONT></I>proxy<B><FONT color=#646464>&lt;</FONT></B>X<B><FONT color=#646464>&gt;</FONT></B> x<B><FONT color=#646464>;</FONT></B> 
x<B><FONT color=#646464>.</FONT></B>connect<B><FONT color=#646464>(</FONT></B><FONT color=#ff00ff>"my_host"</FONT><B><FONT color=#646464>);</FONT></B> 
A a<B><FONT color=#646464>;</FONT></B> 
std<B><FONT color=#646464>::</FONT></B>string s<B><FONT color=#646464>(</FONT></B><FONT color=#ff00ff>"abc"</FONT><B><FONT color=#646464>);</FONT></B><I><FONT color=#008000> 
// … 
</FONT></I>x<B><FONT color=#646464>.</FONT></B>f<B><FONT color=#646464>(</FONT></B>a<B><FONT color=#646464>,</FONT></B> s<B><FONT color=#646464>);</FONT></B> 
<BR></PRE>
<HR>

<P>仅使用一个包装层就完成远程调用？从目前的C＋＋来看基本上不可能。 今天突然想到可以使用aspect c++来生成代码，因为aspect c++在生成代码时，也生成了一些简单的元信息，可以在函数里面取得函数的原型、各参数的类型等。 根据0x的描述，我编写了简单的测试代码： <PRE style="BACKGROUND: #e6e6e6"><FONT color=#a000a0>#include &lt;string&gt;
#include &lt;iostream&gt;
#include &lt;sstream&gt;
#include &lt;vector&gt;
</FONT><B><FONT color=#0000ff>using namespace</FONT></B> std<B><FONT color=#646464>;</FONT></B><B><FONT color=#0000ff>

class</FONT></B> LoginService<B><FONT color=#646464>
{</FONT></B><B><FONT color=#0000ff>
public</FONT></B><B><FONT color=#646464>:</FONT></B><B><FONT color=#0000ff>
	virtual</FONT></B><B><FONT color=#0000ff> bool</FONT></B> login<B><FONT color=#646464> (</FONT></B><B><FONT color=#0000ff>const</FONT></B> string<B><FONT color=#646464>&amp;</FONT></B> name<B><FONT color=#646464>,</FONT></B><B><FONT color=#0000ff> const</FONT></B> string<B><FONT color=#646464>&amp;</FONT></B> password<B><FONT color=#646464>,</FONT></B> string<B><FONT color=#646464>&amp;</FONT></B> session<B><FONT color=#646464>) =</FONT></B><FONT color=#800080> 0</FONT><B><FONT color=#646464>;</FONT></B><B><FONT color=#0000ff>
	virtual</FONT></B><B><FONT color=#0000ff> void</FONT></B> logout<B><FONT color=#646464> (</FONT></B><B><FONT color=#0000ff>const</FONT></B> string<B><FONT color=#646464>&amp;</FONT></B> session<B><FONT color=#646464>) =</FONT></B><FONT color=#800080> 0</FONT><B><FONT color=#646464>;
};</FONT></B><B><FONT color=#0000ff>

class</FONT></B> RemoteCall<B><FONT color=#646464>
{</FONT></B><B><FONT color=#0000ff>
public</FONT></B><B><FONT color=#646464>:</FONT></B><B><FONT color=#0000ff>
	bool</FONT></B> connect<B><FONT color=#646464> (</FONT></B><B><FONT color=#0000ff>const</FONT></B><B><FONT color=#0000ff> char</FONT></B><B><FONT color=#646464>*</FONT></B> host<B><FONT color=#646464>,</FONT></B><B><FONT color=#0000ff> unsigned short</FONT></B> port<B><FONT color=#646464>)
	{</FONT></B>
		cout<B><FONT color=#646464> &lt;&lt;</FONT></B><FONT color=#ff00ff> "connect success"</FONT><B><FONT color=#646464> &lt;&lt;</FONT></B> endl<B><FONT color=#646464>;</FONT></B><B><FONT color=#0000ff>
		return</FONT></B><B><FONT color=#800080> true</FONT></B><B><FONT color=#646464>;
	}</FONT></B><B><FONT color=#0000ff>
	bool</FONT></B> send<B><FONT color=#646464> (</FONT></B><B><FONT color=#0000ff>const</FONT></B><B><FONT color=#0000ff> char</FONT></B><B><FONT color=#646464>*</FONT></B> p<B><FONT color=#646464>,</FONT></B> size_t len<B><FONT color=#646464>)
	{</FONT></B>
		cout<B><FONT color=#646464> &lt;&lt;</FONT></B><FONT color=#ff00ff> "send: "</FONT><B><FONT color=#646464> &lt;&lt;</FONT></B> endl<B><FONT color=#646464>;</FONT></B>
		cout<B><FONT color=#646464> &lt;&lt;</FONT></B> string<B><FONT color=#646464>(</FONT></B>p<B><FONT color=#646464>,</FONT></B> len<B><FONT color=#646464>) &lt;&lt;</FONT></B> endl<B><FONT color=#646464>;</FONT></B><B><FONT color=#0000ff>
		return</FONT></B><B><FONT color=#800080> true</FONT></B><B><FONT color=#646464>;
	}</FONT></B><B><FONT color=#0000ff>
	bool</FONT></B> recv<B><FONT color=#646464>(</FONT></B><B><FONT color=#0000ff>char</FONT></B><B><FONT color=#646464>*</FONT></B> p<B><FONT color=#646464>,</FONT></B> size_t len<B><FONT color=#646464>)
	{</FONT></B><B><FONT color=#0000ff>
		return</FONT></B><B><FONT color=#800080> true</FONT></B><B><FONT color=#646464>;
	}
};</FONT></B><B><FONT color=#0000ff>

class</FONT></B> RemoteLoginService<B><FONT color=#646464> :</FONT></B><B><FONT color=#0000ff> public</FONT></B> LoginService<B><FONT color=#646464>,</FONT></B><B><FONT color=#0000ff> public</FONT></B> RemoteCall<B><FONT color=#646464>
{</FONT></B><B><FONT color=#0000ff>
public</FONT></B><B><FONT color=#646464>:</FONT></B><B><FONT color=#0000ff>
	virtual</FONT></B><B><FONT color=#0000ff> bool</FONT></B> login<B><FONT color=#646464> (</FONT></B><B><FONT color=#0000ff>const</FONT></B> string<B><FONT color=#646464>&amp;</FONT></B> name<B><FONT color=#646464>,</FONT></B><B><FONT color=#0000ff> const</FONT></B> string<B><FONT color=#646464>&amp;</FONT></B> password<B><FONT color=#646464>,</FONT></B> string<B><FONT color=#646464>&amp;</FONT></B> session<B><FONT color=#646464>)
	{</FONT></B><B><FONT color=#0000ff>
		return</FONT></B><B><FONT color=#800080> false</FONT></B><B><FONT color=#646464>;
	}</FONT></B><B><FONT color=#0000ff>
	virtual</FONT></B><B><FONT color=#0000ff> void</FONT></B> logout<B><FONT color=#646464> (</FONT></B><B><FONT color=#0000ff>const</FONT></B> string<B><FONT color=#646464>&amp;</FONT></B> session<B><FONT color=#646464>)
	{
	}
};</FONT></B><B><FONT color=#0000ff>

int</FONT></B><B><FONT color=#0000ff> main</FONT></B><B><FONT color=#646464>(</FONT></B><B><FONT color=#0000ff>int</FONT></B> argc<B><FONT color=#646464>,</FONT></B><B><FONT color=#0000ff> char</FONT></B><B><FONT color=#646464> *</FONT></B>argv<B><FONT color=#646464>[])
{</FONT></B>
	RemoteLoginService rls<B><FONT color=#646464>;</FONT></B>
	rls<B><FONT color=#646464>.</FONT></B>connect<B><FONT color=#646464>(</FONT></B><FONT color=#ff00ff>"localhost"</FONT><B><FONT color=#646464>,</FONT></B><FONT color=#800080> 3957</FONT><B><FONT color=#646464>);</FONT></B>
	string session<B><FONT color=#646464>;</FONT></B>
	rls<B><FONT color=#646464>.</FONT></B>login<B><FONT color=#646464>(</FONT></B><FONT color=#ff00ff>"lijie"</FONT><B><FONT color=#646464>,</FONT></B><FONT color=#ff00ff> "lijie"</FONT><B><FONT color=#646464>,</FONT></B> session<B><FONT color=#646464>);</FONT></B>
	rls<B><FONT color=#646464>.</FONT></B>logout<B><FONT color=#646464>(</FONT></B>session<B><FONT color=#646464>);</FONT></B><B><FONT color=#0000ff>
	
	return</FONT></B><FONT color=#800080> 0</FONT><B><FONT color=#646464>;
}</FONT></B>
</PRE>
<HR>
现在的目标是加入一个方面，让RemoteLoginService具有远程调用功能。当然由于此处RemoteCall并未实现，所以只要能够把这个调用正确序列化就算完成目标。 这个方面完成后如下： <PRE style="BACKGROUND: #e6e6e6">aspect Remote<B><FONT color=#646464>
{</FONT></B>
	pointcut remote_class<B><FONT color=#646464>() =</FONT></B><FONT color=#ff00ff> "RemoteCall"</FONT><B><FONT color=#646464>;</FONT></B>
	pointcut remote_call<B><FONT color=#646464>() =</FONT></B> derived<B><FONT color=#646464>(</FONT></B>remote_class<B><FONT color=#646464>()) &amp;&amp; !</FONT></B>remote_class<B><FONT color=#646464>();</FONT></B>

	pointcut virtual_methods<B><FONT color=#646464>() =</FONT></B><FONT color=#ff00ff> "% ...::%(...)"</FONT><B><FONT color=#646464>;</FONT></B>

	advice within<B><FONT color=#646464>(</FONT></B>remote_call<B><FONT color=#646464>()) &amp;&amp;</FONT></B> execution<B><FONT color=#646464>(</FONT></B>virtual_methods<B><FONT color=#646464>()):</FONT></B> before<B><FONT color=#646464>(){</FONT></B>
		stringstream ss<B><FONT color=#646464>;</FONT></B>
		ss<B><FONT color=#646464> &lt;&lt;</FONT></B><FONT color=#ff00ff> "\tcall:"</FONT><B><FONT color=#646464> &lt;&lt;</FONT></B> JoinPoint<B><FONT color=#646464>::</FONT></B>signature<B><FONT color=#646464>() &lt;&lt;</FONT></B> endl<B><FONT color=#646464>;</FONT></B>
		ss<B><FONT color=#646464> &lt;&lt;</FONT></B><FONT color=#ff00ff> "\targuments:"</FONT><B><FONT color=#646464>;</FONT></B><B><FONT color=#0000ff>
		for</FONT></B><B><FONT color=#646464> (</FONT></B>size_t i<B><FONT color=#646464>=</FONT></B><FONT color=#800080>0</FONT><B><FONT color=#646464>;</FONT></B> i<B><FONT color=#646464>&lt;</FONT></B>JoinPoint<B><FONT color=#646464>::</FONT></B>args<B><FONT color=#646464>(); ++</FONT></B>i<B><FONT color=#646464>)
		{</FONT></B>
			string arg<B><FONT color=#646464>(</FONT></B>tjp<B><FONT color=#646464>-&gt;</FONT></B>argtype<B><FONT color=#646464>(</FONT></B>i<B><FONT color=#646464>));</FONT></B><B><FONT color=#0000ff>
			if</FONT></B><B><FONT color=#646464> (</FONT></B>arg<B><FONT color=#646464>.</FONT></B>find<B><FONT color=#646464>(</FONT></B><FONT color=#ff00ff>"basic_string"</FONT><B><FONT color=#646464>) !=</FONT></B> arg<B><FONT color=#646464>.</FONT></B>npos<B><FONT color=#646464>)
			{</FONT></B>
				ss<B><FONT color=#646464> &lt;&lt; *(</FONT></B>string<B><FONT color=#646464>*)</FONT></B>tjp<B><FONT color=#646464>-&gt;</FONT></B>arg<B><FONT color=#646464>(</FONT></B>i<B><FONT color=#646464>) &lt;&lt;</FONT></B><FONT color=#ff00ff> "|"</FONT><B><FONT color=#646464>;
			}
		}</FONT></B>
		string send_str<B><FONT color=#646464> =</FONT></B> ss<B><FONT color=#646464>.</FONT></B>str<B><FONT color=#646464>();</FONT></B>
		tjp<B><FONT color=#646464>-&gt;</FONT></B>target<B><FONT color=#646464>()-&gt;</FONT></B>send<B><FONT color=#646464> (</FONT></B>send_str<B><FONT color=#646464>.</FONT></B>c_str<B><FONT color=#646464>(),</FONT></B> send_str<B><FONT color=#646464>.</FONT></B>size<B><FONT color=#646464>());
	}</FONT></B>

	advice within<B><FONT color=#646464>(</FONT></B>remote_call<B><FONT color=#646464>()) &amp;&amp;</FONT></B> execution<B><FONT color=#646464>(</FONT></B>virtual_methods<B><FONT color=#646464>()):</FONT></B> after<B><FONT color=#646464>(){</FONT></B>
		vector<B><FONT color=#646464>&lt;</FONT></B><B><FONT color=#0000ff>char</FONT></B><B><FONT color=#646464>&gt;</FONT></B> buffer<B><FONT color=#646464>(</FONT></B><FONT color=#800080>1024</FONT><B><FONT color=#646464>,</FONT></B><FONT color=#ff00ff> '\0'</FONT><B><FONT color=#646464>);</FONT></B>
		tjp<B><FONT color=#646464>-&gt;</FONT></B>target<B><FONT color=#646464>()-&gt;</FONT></B>recv<B><FONT color=#646464> (&amp;(*</FONT></B>buffer<B><FONT color=#646464>.</FONT></B>begin<B><FONT color=#646464>()),</FONT></B> buffer<B><FONT color=#646464>.</FONT></B>size<B><FONT color=#646464>());</FONT></B><I><FONT color=#008000>
		// 解析接收的数据，远程调用结果写入tjp-&gt;result()指向的内存
</FONT></I><B><FONT color=#646464>	}
};</FONT></B></PRE>
<HR>
它匹配所有从RemoteCall上派生的类，为它的每个方法加入远程调用代码以及调用结果处理代码。 生成并编译运行，输出如下： <BR>connect success <BR>send: <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; call:bool RemoteLoginService::login(const ::std::basic_string&lt; char &gt; &amp;,const ::std::basic_string&lt; char &gt; &amp;,::std::basic_string&lt; char &gt; &amp;) <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; arguments:lijie|lijie|| <BR>send: <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; call:void RemoteLoginService::logout(const ::std::basic_string&lt; char &gt; &amp;) <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; arguments:| <BR><BR>由于完整序列化了各个参数值，第一个目标——生成远程调用代码——算是完成了。 <BR><BR>下一个目标，考虑服务端如何编写？服务端需要开启一个服务，并注册各个服务接口。 <BR><BR>要达到这个目标，aspect c++需要提供类、方法级别的类型及名称获取，不过aspect c++在这方面没有提供更多方便，现在只能在方法执行时获得方法的信息，它所生成的“元信息”过于简单，而且为了效率考虑都实现为各个独立的结构，结构的成员也大都是static的，所以无法使用一个合适的接口来反射，期待以后能加入这些特性。 <BR><BR>所以这第2个目标实际上无法简单地完成，除非在服务端手工添加服务注册代码，这个部分工作量稍小，但还是可以做到的。<img src ="http://www.cppblog.com/cpunion/aggbug/1888.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cpunion/" target="_blank">qiezi</a> 2005-12-19 22:50 <a href="http://www.cppblog.com/cpunion/archive/2005/12/19/1888.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>［C++之AOP］实战Aspect C++之观察者模式</title><link>http://www.cppblog.com/cpunion/archive/2005/12/17/1842.html</link><dc:creator>qiezi</dc:creator><author>qiezi</author><pubDate>Sat, 17 Dec 2005 02:21:00 GMT</pubDate><guid>http://www.cppblog.com/cpunion/archive/2005/12/17/1842.html</guid><wfw:comment>http://www.cppblog.com/cpunion/comments/1842.html</wfw:comment><comments>http://www.cppblog.com/cpunion/archive/2005/12/17/1842.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/cpunion/comments/commentRss/1842.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/cpunion/services/trackbacks/1842.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 关于Aspect C++以及AOP，还有许多话题，不过不打算再继续了，AOP是个广泛的议题，局限在某一实现上只会使我们眼界变窄。&nbsp;&nbsp;<a href='http://www.cppblog.com/cpunion/archive/2005/12/17/1842.html'>阅读全文</a><img src ="http://www.cppblog.com/cpunion/aggbug/1842.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cpunion/" target="_blank">qiezi</a> 2005-12-17 10:21 <a href="http://www.cppblog.com/cpunion/archive/2005/12/17/1842.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>［C++之AOP］实战Aspect C++之检查内存泄漏</title><link>http://www.cppblog.com/cpunion/archive/2005/12/16/1836.html</link><dc:creator>qiezi</dc:creator><author>qiezi</author><pubDate>Fri, 16 Dec 2005 14:38:00 GMT</pubDate><guid>http://www.cppblog.com/cpunion/archive/2005/12/16/1836.html</guid><wfw:comment>http://www.cppblog.com/cpunion/comments/1836.html</wfw:comment><comments>http://www.cppblog.com/cpunion/archive/2005/12/16/1836.html#Feedback</comments><slash:comments>5</slash:comments><wfw:commentRss>http://www.cppblog.com/cpunion/comments/commentRss/1836.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/cpunion/services/trackbacks/1836.html</trackback:ping><description><![CDATA[前面简单介绍了Aspect C++，相信没人看出它有什么特别强大的地方。<BR><BR>这次特别挑了一个合适的例子，检查内存泄漏。<BR><BR>首先看一个普通的程序：<BR>1、test.h<BR>
<DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><SPAN style="COLOR: #000000">#ifndef&nbsp;__TEST_H__<BR></SPAN><SPAN style="COLOR: #0000ff">#define</SPAN><SPAN style="COLOR: #000000">&nbsp;__TEST_H__</SPAN><SPAN style="COLOR: #000000"><BR><BR></SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000">&nbsp;Test1<BR>{<BR>};<BR><BR></SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000">&nbsp;Test2<BR>{<BR>};<BR><BR></SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000">&nbsp;Test3<BR>{<BR>};<BR><BR></SPAN><SPAN style="COLOR: #0000ff">#endif</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000">&nbsp;__TEST_H__</SPAN><SPAN style="COLOR: #000000"><BR></SPAN></DIV>2、main.cc<BR>
<DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><SPAN style="COLOR: #000000">#include&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">test.h</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000"><BR><BR></SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&nbsp;main&nbsp;()<BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;Test1&nbsp;test1;<BR>&nbsp;&nbsp;&nbsp;&nbsp;Test2&nbsp;test2;<BR>&nbsp;&nbsp;&nbsp;&nbsp;Test3&nbsp;test3;<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">new</SPAN><SPAN style="COLOR: #000000">&nbsp;Test1();<BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">new</SPAN><SPAN style="COLOR: #000000">&nbsp;Test2();<BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">new</SPAN><SPAN style="COLOR: #000000">&nbsp;Test2();<BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">new</SPAN><SPAN style="COLOR: #000000">&nbsp;Test1();<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">new</SPAN><SPAN style="COLOR: #000000">&nbsp;Test1(test1);<BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">new</SPAN><SPAN style="COLOR: #000000">&nbsp;Test3(test3);<BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">return</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">0</SPAN><SPAN style="COLOR: #000000">;<BR>}<BR></SPAN></DIV><BR>这个程序会有6个对象泄漏。如果是在很隐蔽的地方分配对象，如何能够快速查找出来呢？<BR><BR>采用Aspect C++，我们可以在构造函数和析构函数中插入代码，帮助检查内存泄漏。<BR><BR>首先实现一个内存分配记录管理器：<BR>1、memory_recorder.h<BR>
<DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><SPAN style="COLOR: #000000">#ifndef&nbsp;__MEMORY_RECORDER_H__<BR></SPAN><SPAN style="COLOR: #0000ff">#define</SPAN><SPAN style="COLOR: #000000">&nbsp;__MEMORY_RECORDER_H__</SPAN><SPAN style="COLOR: #000000"><BR><BR>#include&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">map</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000"><BR>#include&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">typeinfo</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #0000ff">using</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">namespace</SPAN><SPAN style="COLOR: #000000">&nbsp;std;<BR><BR></SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000">&nbsp;MemoryRecorder<BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;map</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000">,&nbsp;</SPAN><SPAN style="COLOR: #0000ff">const</SPAN><SPAN style="COLOR: #000000">&nbsp;type_info</SPAN><SPAN style="COLOR: #000000">*&gt;</SPAN><SPAN style="COLOR: #000000">&nbsp;objects;<BR></SPAN><SPAN style="COLOR: #0000ff">public</SPAN><SPAN style="COLOR: #000000">:<BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #000000">~</SPAN><SPAN style="COLOR: #000000">MemoryRecorder&nbsp;();<BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">&nbsp;addObject(</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000">&nbsp;obj,&nbsp;</SPAN><SPAN style="COLOR: #0000ff">const</SPAN><SPAN style="COLOR: #000000">&nbsp;type_info</SPAN><SPAN style="COLOR: #000000">&amp;</SPAN><SPAN style="COLOR: #000000">&nbsp;ti);<BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">&nbsp;removeObject(</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000">&nbsp;obj,&nbsp;</SPAN><SPAN style="COLOR: #0000ff">const</SPAN><SPAN style="COLOR: #000000">&nbsp;type_info</SPAN><SPAN style="COLOR: #000000">&amp;</SPAN><SPAN style="COLOR: #000000">&nbsp;ti);<BR>};<BR><BR></SPAN><SPAN style="COLOR: #0000ff">extern</SPAN><SPAN style="COLOR: #000000">&nbsp;MemoryRecorder&nbsp;g_memoryRecorder;<BR><BR></SPAN><SPAN style="COLOR: #0000ff">#endif</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000">&nbsp;__MEMORY_RECORDER_H__</SPAN><SPAN style="COLOR: #000000"><BR></SPAN></DIV>2、memory_recorder.cc<BR>
<DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><SPAN style="COLOR: #000000">#include&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">memory_recorder.h</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000"><BR><BR>#include&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">iostream</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #0000ff">using</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">namespace</SPAN><SPAN style="COLOR: #000000">&nbsp;std;<BR><BR><BR>MemoryRecorder&nbsp;g_memoryRecorder;<BR><BR><BR>MemoryRecorder::</SPAN><SPAN style="COLOR: #000000">~</SPAN><SPAN style="COLOR: #000000">MemoryRecorder&nbsp;()<BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">if</SPAN><SPAN style="COLOR: #000000">&nbsp;(objects.size()&nbsp;</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">0</SPAN><SPAN style="COLOR: #000000">)<BR>&nbsp;&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cout&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;&lt;</SPAN><SPAN style="COLOR: #000000">&nbsp;objects.size()&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;&lt;</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">&nbsp;objects&nbsp;not&nbsp;released:</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;&lt;</SPAN><SPAN style="COLOR: #000000">&nbsp;endl;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">for</SPAN><SPAN style="COLOR: #000000">&nbsp;(map</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000">,&nbsp;</SPAN><SPAN style="COLOR: #0000ff">const</SPAN><SPAN style="COLOR: #000000">&nbsp;type_info</SPAN><SPAN style="COLOR: #000000">*&gt;</SPAN><SPAN style="COLOR: #000000">::const_iterator&nbsp;iter&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;objects.begin();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;iter&nbsp;</SPAN><SPAN style="COLOR: #000000">!=</SPAN><SPAN style="COLOR: #000000">&nbsp;objects.end();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;iter&nbsp;</SPAN><SPAN style="COLOR: #000000">++</SPAN><SPAN style="COLOR: #000000">)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cout&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;&lt;</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">\t</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;&lt;</SPAN><SPAN style="COLOR: #000000">&nbsp;iter</SPAN><SPAN style="COLOR: #000000">-&gt;</SPAN><SPAN style="COLOR: #000000">second</SPAN><SPAN style="COLOR: #000000">-&gt;</SPAN><SPAN style="COLOR: #000000">name()&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;&lt;</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">:&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;&lt;</SPAN><SPAN style="COLOR: #000000">&nbsp;(iter</SPAN><SPAN style="COLOR: #000000">-&gt;</SPAN><SPAN style="COLOR: #000000">first)&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;&lt;</SPAN><SPAN style="COLOR: #000000">&nbsp;endl;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;delete&nbsp;(iter</SPAN><SPAN style="COLOR: #000000">-&gt;</SPAN><SPAN style="COLOR: #000000">first);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR>}<BR><BR></SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">&nbsp;MemoryRecorder::addObject(</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000">&nbsp;obj,&nbsp;</SPAN><SPAN style="COLOR: #0000ff">const</SPAN><SPAN style="COLOR: #000000">&nbsp;type_info</SPAN><SPAN style="COLOR: #000000">&amp;</SPAN><SPAN style="COLOR: #000000">&nbsp;ti)<BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;objects.insert(make_pair(obj,&nbsp;</SPAN><SPAN style="COLOR: #000000">&amp;</SPAN><SPAN style="COLOR: #000000">ti));<BR>}<BR><BR></SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">&nbsp;MemoryRecorder::removeObject(</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000">&nbsp;obj,&nbsp;</SPAN><SPAN style="COLOR: #0000ff">const</SPAN><SPAN style="COLOR: #000000">&nbsp;type_info</SPAN><SPAN style="COLOR: #000000">&amp;</SPAN><SPAN style="COLOR: #000000">&nbsp;ti)<BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;objects.erase(obj);<BR>}<BR></SPAN></DIV>3、实现方面，test.ah<BR>
<DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><SPAN style="COLOR: #000000">#ifndef&nbsp;__TEST_AH__<BR></SPAN><SPAN style="COLOR: #0000ff">#define</SPAN><SPAN style="COLOR: #000000">&nbsp;__TEST_AH__</SPAN><SPAN style="COLOR: #000000"><BR><BR>#include&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">memory_recorder.h</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000"><BR><STRIKE>#include&nbsp;</STRIKE></SPAN><STRIKE><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">iostream</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN></STRIKE><SPAN style="COLOR: #000000"><BR></SPAN><STRIKE><SPAN style="COLOR: #0000ff">using</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">namespace</SPAN></STRIKE><SPAN style="COLOR: #000000"><STRIKE>&nbsp;std;</STRIKE><BR><BR>aspect&nbsp;MemberRecorder<BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;pointcut&nbsp;all_class()&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;classes(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">Test%</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">);<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;advice&nbsp;construction&nbsp;(all_class())&nbsp;:&nbsp;after&nbsp;()<BR>&nbsp;&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;g_memoryRecorder.addObject&nbsp;(tjp</SPAN><SPAN style="COLOR: #000000">-&gt;</SPAN><SPAN style="COLOR: #000000">target(),&nbsp;typeid(</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000">tjp</SPAN><SPAN style="COLOR: #000000">-&gt;</SPAN><SPAN style="COLOR: #000000">target()));<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;advice&nbsp;destruction&nbsp;(all_class())&nbsp;:&nbsp;after&nbsp;()<BR>&nbsp;&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;g_memoryRecorder.removeObject&nbsp;(tjp</SPAN><SPAN style="COLOR: #000000">-&gt;</SPAN><SPAN style="COLOR: #000000">target(),&nbsp;typeid(</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000">tjp</SPAN><SPAN style="COLOR: #000000">-&gt;</SPAN><SPAN style="COLOR: #000000">target()));<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR>};<BR><BR></SPAN><SPAN style="COLOR: #0000ff">#endif</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000">&nbsp;__TEST_AH__</SPAN><SPAN style="COLOR: #000000"><BR></SPAN></DIV><BR>这个方面实现的功能很简单，首先定义了一个pointcut(切面)，它匹配所有以“Test”开头的类。<BR>接下来定义了2个处理方法，分别在这些类的构造函数和析构函数调用之后执行。<BR><BR>tjp-&gt;target()指向Test*对象实例，其它的不详细说明了，应该都比较容易懂。<BR><BR>顺便说一下，前一篇里说源文件可以保存为.cpp文件，实际上是错误的，它只处理.h和.cc文件。<BR><BR>运行ac++产生代码，编译运行后效果如下：<BR>F:\projects\aspectc-out&gt;main<BR>6 objects not released:<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; class Test1: 00372B40<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; class Test1: 00372B70<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; class Test3: 00372BA0<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; class Test1: 00374F90<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; class Test2: 00374FC0<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; class Test2: 00374FF0<BR><BR>另外，产生代码时最好是使用mingw，配置方便一些，不影响产生后的代码，产生后的代码可以使用VC编译。<img src ="http://www.cppblog.com/cpunion/aggbug/1836.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cpunion/" target="_blank">qiezi</a> 2005-12-16 22:38 <a href="http://www.cppblog.com/cpunion/archive/2005/12/16/1836.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C++之AOP</title><link>http://www.cppblog.com/cpunion/archive/2005/12/15/1795.html</link><dc:creator>qiezi</dc:creator><author>qiezi</author><pubDate>Thu, 15 Dec 2005 07:43:00 GMT</pubDate><guid>http://www.cppblog.com/cpunion/archive/2005/12/15/1795.html</guid><wfw:comment>http://www.cppblog.com/cpunion/comments/1795.html</wfw:comment><comments>http://www.cppblog.com/cpunion/archive/2005/12/15/1795.html#Feedback</comments><slash:comments>7</slash:comments><wfw:commentRss>http://www.cppblog.com/cpunion/comments/commentRss/1795.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/cpunion/services/trackbacks/1795.html</trackback:ping><description><![CDATA[AOP是近年炒得很热，但却用得很少的一门技术，不过这并不能阻止我去学习它。既然能一度炒得火热，必定有过人之处。说AOP是一种思想或许更适合一些，它并不描述哪一种专有的技术，也不指定实现方式。<BR><BR>众所周知，C++没有丰富的动态类型信息，更没有动态生成类的功能(C++类型在编译后就基本上没有类型存在了)，所以无法像java一样采用动态代理来实现AOP。<BR><BR>Aspect C++是C++的一个AOP实现，它使用了插入代码的方法。<BR><BR>一个典型的Aspect C++示例需要一个C++源文件(.cpp)、一个Aspect C++源文件(.ah)，通过ac++编译器把C++源文件和Aspect C++源文件转换成混合的C++源文件(如果有头文件也会转换)，最后通过普通的C++编译器编译出可执行文件。<BR><BR>下面是一个简单的示例：<BR><BR>1、C++源文件：<BR>
<DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><SPAN style="COLOR: #000000">#include&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">stdio.h</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000"><BR><BR></SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000">&nbsp;A&nbsp;{<BR></SPAN><SPAN style="COLOR: #0000ff">public</SPAN><SPAN style="COLOR: #000000">:<BR>&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&nbsp;a(</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&nbsp;i,&nbsp;</SPAN><SPAN style="COLOR: #0000ff">float</SPAN><SPAN style="COLOR: #000000">&nbsp;b);<BR>};<BR><BR></SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&nbsp;A::a(</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&nbsp;i,&nbsp;</SPAN><SPAN style="COLOR: #0000ff">float</SPAN><SPAN style="COLOR: #000000">&nbsp;b)&nbsp;{<BR>&nbsp;&nbsp;printf(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">inside&nbsp;A::a(%d,&nbsp;%f)\n</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">,&nbsp;i,&nbsp;b);<BR>&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">return</SPAN><SPAN style="COLOR: #000000">&nbsp;i;<BR>}<BR><BR></SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">&nbsp;b(</SPAN><SPAN style="COLOR: #0000ff">char</SPAN><SPAN style="COLOR: #000000">&nbsp;c,&nbsp;</SPAN><SPAN style="COLOR: #0000ff">char</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000">str)&nbsp;{<BR>&nbsp;&nbsp;printf(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">inside&nbsp;b(%c,&nbsp;%s)\n</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">,&nbsp;c,&nbsp;str);<BR>}<BR><BR></SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&nbsp;main()&nbsp;{<BR>&nbsp;&nbsp;A&nbsp;a;<BR>&nbsp;&nbsp;a.a(</SPAN><SPAN style="COLOR: #000000">4711</SPAN><SPAN style="COLOR: #000000">,&nbsp;</SPAN><SPAN style="COLOR: #000000">3.14</SPAN><SPAN style="COLOR: #000000">);<BR>&nbsp;&nbsp;b(</SPAN><SPAN style="COLOR: #000000">'</SPAN><SPAN style="COLOR: #000000">H</SPAN><SPAN style="COLOR: #000000">'</SPAN><SPAN style="COLOR: #000000">,&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">ello&nbsp;World</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">);<BR>&nbsp; return 0;<BR>}</SPAN></DIV><BR>2、Aspect C++源文件：<BR>
<DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><SPAN style="COLOR: #000000">#include&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">stdio.h</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000"><BR><BR>aspect&nbsp;Action&nbsp;{<BR>&nbsp;&nbsp;advice&nbsp;execution(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">%&nbsp;A::%(<IMG src="http://www.cppblog.com/images/dot.gif">)</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">)&nbsp;</SPAN><SPAN style="COLOR: #000000">||</SPAN><SPAN style="COLOR: #000000">&nbsp;execution(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">%&nbsp;b(<IMG src="http://www.cppblog.com/images/dot.gif">)</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">)&nbsp;:&nbsp;around()&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;printf(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">A:&nbsp;before(exec)&nbsp;%s\n</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">,&nbsp;JoinPoint::signature());<BR>&nbsp;&nbsp;&nbsp;&nbsp;printf(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">that&nbsp;&nbsp;:&nbsp;%p\n</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">&nbsp;,&nbsp;tjp</SPAN><SPAN style="COLOR: #000000">-&gt;</SPAN><SPAN style="COLOR: #000000">that());<BR>&nbsp;&nbsp;&nbsp;&nbsp;printf(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">target:&nbsp;%p\n</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">&nbsp;,tjp</SPAN><SPAN style="COLOR: #000000">-&gt;</SPAN><SPAN style="COLOR: #000000">target());<BR>&nbsp;&nbsp;&nbsp;&nbsp;tjp</SPAN><SPAN style="COLOR: #000000">-&gt;</SPAN><SPAN style="COLOR: #000000">proceed();<BR>&nbsp;&nbsp;&nbsp;&nbsp;printf(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">A:&nbsp;after(exec)&nbsp;%s\n</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">,&nbsp;JoinPoint::signature());<BR>&nbsp;&nbsp;}<BR>&nbsp;&nbsp;advice&nbsp;call(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">%&nbsp;A::%(<IMG src="http://www.cppblog.com/images/dot.gif">)</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">)&nbsp;</SPAN><SPAN style="COLOR: #000000">||</SPAN><SPAN style="COLOR: #000000">&nbsp;call(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">%&nbsp;b(<IMG src="http://www.cppblog.com/images/dot.gif">)</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">)&nbsp;:&nbsp;around()&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;printf(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">A:&nbsp;before(call)&nbsp;%s\n</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">,&nbsp;JoinPoint::signature());<BR>&nbsp;&nbsp;&nbsp;&nbsp;printf(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">that&nbsp;&nbsp;:&nbsp;%p\n</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">&nbsp;,&nbsp;tjp</SPAN><SPAN style="COLOR: #000000">-&gt;</SPAN><SPAN style="COLOR: #000000">that());<BR>&nbsp;&nbsp;&nbsp;&nbsp;printf(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">target:&nbsp;%p\n</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">&nbsp;,tjp</SPAN><SPAN style="COLOR: #000000">-&gt;</SPAN><SPAN style="COLOR: #000000">target());<BR>&nbsp;&nbsp;&nbsp;&nbsp;tjp</SPAN><SPAN style="COLOR: #000000">-&gt;</SPAN><SPAN style="COLOR: #000000">proceed();<BR>&nbsp;&nbsp;&nbsp;&nbsp;printf(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">A:&nbsp;after(call)&nbsp;%s\n</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">,&nbsp;JoinPoint::signature());<BR>&nbsp;&nbsp;}<BR>};<BR><BR>aspect&nbsp;ActionB&nbsp;{<BR>&nbsp;&nbsp;advice&nbsp;execution(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">%&nbsp;A::%(<IMG src="http://www.cppblog.com/images/dot.gif">)</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">)&nbsp;</SPAN><SPAN style="COLOR: #000000">||</SPAN><SPAN style="COLOR: #000000">&nbsp;execution(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">%&nbsp;b(<IMG src="http://www.cppblog.com/images/dot.gif">)</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">)&nbsp;:&nbsp;around()&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;printf(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">B:&nbsp;before(exec)&nbsp;%s\n</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">,&nbsp;JoinPoint::signature());<BR>&nbsp;&nbsp;&nbsp;&nbsp;printf(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">that&nbsp;&nbsp;:&nbsp;%p\n</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">&nbsp;,&nbsp;tjp</SPAN><SPAN style="COLOR: #000000">-&gt;</SPAN><SPAN style="COLOR: #000000">that());<BR>&nbsp;&nbsp;&nbsp;&nbsp;printf(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">target:&nbsp;%p\n</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">&nbsp;,tjp</SPAN><SPAN style="COLOR: #000000">-&gt;</SPAN><SPAN style="COLOR: #000000">target());<BR>&nbsp;&nbsp;&nbsp;&nbsp;tjp</SPAN><SPAN style="COLOR: #000000">-&gt;</SPAN><SPAN style="COLOR: #000000">proceed();<BR>&nbsp;&nbsp;&nbsp;&nbsp;printf(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">B:&nbsp;after(exec)&nbsp;%s\n</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">,&nbsp;JoinPoint::signature());<BR>&nbsp;&nbsp;}<BR>&nbsp;&nbsp;advice&nbsp;call(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">%&nbsp;A::%(<IMG src="http://www.cppblog.com/images/dot.gif">)</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">)&nbsp;</SPAN><SPAN style="COLOR: #000000">||</SPAN><SPAN style="COLOR: #000000">&nbsp;call(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">%&nbsp;b(<IMG src="http://www.cppblog.com/images/dot.gif">)</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">)&nbsp;:&nbsp;around()&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;printf(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">B:&nbsp;before(call)&nbsp;%s\n</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">,&nbsp;JoinPoint::signature());<BR>&nbsp;&nbsp;&nbsp;&nbsp;printf(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">that&nbsp;&nbsp;:&nbsp;%p\n</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">&nbsp;,&nbsp;tjp</SPAN><SPAN style="COLOR: #000000">-&gt;</SPAN><SPAN style="COLOR: #000000">that());<BR>&nbsp;&nbsp;&nbsp;&nbsp;printf(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">target:&nbsp;%p\n</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">&nbsp;,tjp</SPAN><SPAN style="COLOR: #000000">-&gt;</SPAN><SPAN style="COLOR: #000000">target());<BR>&nbsp;&nbsp;&nbsp;&nbsp;tjp</SPAN><SPAN style="COLOR: #000000">-&gt;</SPAN><SPAN style="COLOR: #000000">proceed();<BR>&nbsp;&nbsp;&nbsp;&nbsp;printf(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">B:&nbsp;after(call)&nbsp;%s\n</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">,&nbsp;JoinPoint::signature());<BR>&nbsp;&nbsp;}<BR>};<BR></SPAN></DIV><BR>简单说明一下：<BR>1、“aspect Action”定义了一个“方面”，名字是“Action”，定义一个方面可以理解为“我关注程序的这个方面”。<BR>2、“advice&nbsp;切入点:位置”定义一个“处理方法”，在切入点的指定位置上执行代码。切入点可以选择call、execution、construction、destruction，分别表示调用、执行、构造函数、析构函数。执行点可以选择before、after、around，分别表示在这些切入点的前面、后面或替换掉整个函数。<BR>3、tpj表示thisJoinPoint，表示切入点本身。上面的例子由于使用around替换了整个执行过程，所以要执行原来的操作还需要调用tpj-&gt;proceed()。这里的around完成的功能可由一个before和一个after代替<BR>4、切入点的匹配模式。切入点通过字符串来匹配要切入的操作，“%”字符表示匹配任意类型(或名字)，在AspectJ中，这个字符是“*”，由于C++中“*”用来定义指针，所以在Aspect C++中用“%”；“...”用来匹配任意个参数。<BR><BR>编译：<BR>首先运行ac++ -p&nbsp;&lt;你的源文件所在目录&gt; -d&nbsp;&lt;输出文件目录&gt; -I&lt;附加头文件目录&gt;，这一步会转换C++源文件和Aspect C++源文件。<BR><BR>如果在安装了VC，编译时可指定INCLUDE路径及_WIN32宏。<BR>ac++ -p&nbsp;&lt;你的源文件所在目录&gt; -d&nbsp;&lt;输出文件目录&gt; -I&lt;附加头文件目录&gt; -I"C:\Program Files\Microsoft Visual Studio 8\VC\include" -D_WIN32<BR><BR>然后直接编译：<BR>cl &lt;源文件名&gt;.cc<BR><BR>上面这个程序在处理前运行结果如下：<BR>
<DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><SPAN style="COLOR: #000000">F:\soft\ac\examples\Action</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">main<BR>inside&nbsp;A::a(</SPAN><SPAN style="COLOR: #000000">4711</SPAN><SPAN style="COLOR: #000000">,&nbsp;</SPAN><SPAN style="COLOR: #000000">3.140000</SPAN><SPAN style="COLOR: #000000">)<BR>inside&nbsp;b(H,&nbsp;ello&nbsp;World)</SPAN></DIV><BR>经Aspect C++处理后运行结果：<BR>
<DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><SPAN style="COLOR: #000000">F:\soft\ac\examples\Action</SPAN><SPAN style="COLOR: #000000">-</SPAN><SPAN style="COLOR: #0000ff">out</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">main<BR>A:&nbsp;before(call)&nbsp;</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&nbsp;A::a(</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">,</SPAN><SPAN style="COLOR: #0000ff">float</SPAN><SPAN style="COLOR: #000000">)<BR>that&nbsp;&nbsp;:&nbsp;</SPAN><SPAN style="COLOR: #000000">00000000</SPAN><SPAN style="COLOR: #000000"><BR>target:&nbsp;0012FF73<BR>B:&nbsp;before(call)&nbsp;</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&nbsp;A::a(</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">,</SPAN><SPAN style="COLOR: #0000ff">float</SPAN><SPAN style="COLOR: #000000">)<BR>that&nbsp;&nbsp;:&nbsp;</SPAN><SPAN style="COLOR: #000000">00000000</SPAN><SPAN style="COLOR: #000000"><BR>target:&nbsp;0012FF73<BR>A:&nbsp;before(exec)&nbsp;</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&nbsp;A::a(</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">,</SPAN><SPAN style="COLOR: #0000ff">float</SPAN><SPAN style="COLOR: #000000">)<BR>that&nbsp;&nbsp;:&nbsp;0012FF73<BR>target:&nbsp;0012FF73<BR>B:&nbsp;before(exec)&nbsp;</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&nbsp;A::a(</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">,</SPAN><SPAN style="COLOR: #0000ff">float</SPAN><SPAN style="COLOR: #000000">)<BR>that&nbsp;&nbsp;:&nbsp;0012FF73<BR>target:&nbsp;0012FF73<BR>inside&nbsp;A::a(</SPAN><SPAN style="COLOR: #000000">4711</SPAN><SPAN style="COLOR: #000000">,&nbsp;</SPAN><SPAN style="COLOR: #000000">3.140000</SPAN><SPAN style="COLOR: #000000">)<BR>B:&nbsp;after(exec)&nbsp;</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&nbsp;A::a(</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">,</SPAN><SPAN style="COLOR: #0000ff">float</SPAN><SPAN style="COLOR: #000000">)<BR>A:&nbsp;after(exec)&nbsp;</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&nbsp;A::a(</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">,</SPAN><SPAN style="COLOR: #0000ff">float</SPAN><SPAN style="COLOR: #000000">)<BR>B:&nbsp;after(call)&nbsp;</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&nbsp;A::a(</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">,</SPAN><SPAN style="COLOR: #0000ff">float</SPAN><SPAN style="COLOR: #000000">)<BR>A:&nbsp;after(call)&nbsp;</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&nbsp;A::a(</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">,</SPAN><SPAN style="COLOR: #0000ff">float</SPAN><SPAN style="COLOR: #000000">)<BR>A:&nbsp;before(call)&nbsp;</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">&nbsp;b(</SPAN><SPAN style="COLOR: #0000ff">char</SPAN><SPAN style="COLOR: #000000">,</SPAN><SPAN style="COLOR: #0000ff">char</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000">)<BR>that&nbsp;&nbsp;:&nbsp;</SPAN><SPAN style="COLOR: #000000">00000000</SPAN><SPAN style="COLOR: #000000"><BR>target:&nbsp;</SPAN><SPAN style="COLOR: #000000">00000000</SPAN><SPAN style="COLOR: #000000"><BR>B:&nbsp;before(call)&nbsp;</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">&nbsp;b(</SPAN><SPAN style="COLOR: #0000ff">char</SPAN><SPAN style="COLOR: #000000">,</SPAN><SPAN style="COLOR: #0000ff">char</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000">)<BR>that&nbsp;&nbsp;:&nbsp;</SPAN><SPAN style="COLOR: #000000">00000000</SPAN><SPAN style="COLOR: #000000"><BR>target:&nbsp;</SPAN><SPAN style="COLOR: #000000">00000000</SPAN><SPAN style="COLOR: #000000"><BR>A:&nbsp;before(exec)&nbsp;</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">&nbsp;b(</SPAN><SPAN style="COLOR: #0000ff">char</SPAN><SPAN style="COLOR: #000000">,</SPAN><SPAN style="COLOR: #0000ff">char</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000">)<BR>that&nbsp;&nbsp;:&nbsp;</SPAN><SPAN style="COLOR: #000000">00000000</SPAN><SPAN style="COLOR: #000000"><BR>target:&nbsp;</SPAN><SPAN style="COLOR: #000000">00000000</SPAN><SPAN style="COLOR: #000000"><BR>B:&nbsp;before(exec)&nbsp;</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">&nbsp;b(</SPAN><SPAN style="COLOR: #0000ff">char</SPAN><SPAN style="COLOR: #000000">,</SPAN><SPAN style="COLOR: #0000ff">char</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000">)<BR>that&nbsp;&nbsp;:&nbsp;</SPAN><SPAN style="COLOR: #000000">00000000</SPAN><SPAN style="COLOR: #000000"><BR>target:&nbsp;</SPAN><SPAN style="COLOR: #000000">00000000</SPAN><SPAN style="COLOR: #000000"><BR>inside&nbsp;b(H,&nbsp;ello&nbsp;World)<BR>B:&nbsp;after(exec)&nbsp;</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">&nbsp;b(</SPAN><SPAN style="COLOR: #0000ff">char</SPAN><SPAN style="COLOR: #000000">,</SPAN><SPAN style="COLOR: #0000ff">char</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000">)<BR>A:&nbsp;after(exec)&nbsp;</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">&nbsp;b(</SPAN><SPAN style="COLOR: #0000ff">char</SPAN><SPAN style="COLOR: #000000">,</SPAN><SPAN style="COLOR: #0000ff">char</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000">)<BR>B:&nbsp;after(call)&nbsp;</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">&nbsp;b(</SPAN><SPAN style="COLOR: #0000ff">char</SPAN><SPAN style="COLOR: #000000">,</SPAN><SPAN style="COLOR: #0000ff">char</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000">)<BR>A:&nbsp;after(call)&nbsp;</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">&nbsp;b(</SPAN><SPAN style="COLOR: #0000ff">char</SPAN><SPAN style="COLOR: #000000">,</SPAN><SPAN style="COLOR: #0000ff">char</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000">)</SPAN></DIV><BR><img src ="http://www.cppblog.com/cpunion/aggbug/1795.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cpunion/" target="_blank">qiezi</a> 2005-12-15 15:43 <a href="http://www.cppblog.com/cpunion/archive/2005/12/15/1795.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>自己写的一个max函数</title><link>http://www.cppblog.com/cpunion/archive/2005/12/12/1692.html</link><dc:creator>qiezi</dc:creator><author>qiezi</author><pubDate>Mon, 12 Dec 2005 02:45:00 GMT</pubDate><guid>http://www.cppblog.com/cpunion/archive/2005/12/12/1692.html</guid><wfw:comment>http://www.cppblog.com/cpunion/comments/1692.html</wfw:comment><comments>http://www.cppblog.com/cpunion/archive/2005/12/12/1692.html#Feedback</comments><slash:comments>7</slash:comments><wfw:commentRss>http://www.cppblog.com/cpunion/comments/commentRss/1692.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/cpunion/services/trackbacks/1692.html</trackback:ping><description><![CDATA[CSDN上看到有人问能否实现一个效率较高的max函数，效率接近于宏，于是自动动手写了一个。<BR><BR>由于max宏在判断不同类型时，能够返回大的那个类型（表示范围大），所以只能使用模板来进行返回类型的推导。<BR><BR>在VC8上打开O2或Ox优化选项，测试结果是与宏效率相等。<BR><BR>全部实现如下：<BR><BR>
<DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><SPAN style="COLOR: #000000">#include&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">typeinfo</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000"><BR>#include&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">cassert</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000"><BR>#include&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">windows.h</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000"><BR>#include&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">iostream</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000"><BR><BR><BR>template&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000">&nbsp;T,&nbsp;</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000">&nbsp;U,&nbsp;</SPAN><SPAN style="COLOR: #0000ff">bool</SPAN><SPAN style="COLOR: #000000">&nbsp;B</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #0000ff">struct</SPAN><SPAN style="COLOR: #000000">&nbsp;BigType<BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;T&nbsp;result;<BR>};<BR><BR>template&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000">&nbsp;T,&nbsp;</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000">&nbsp;U</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #0000ff">struct</SPAN><SPAN style="COLOR: #000000">&nbsp;BigType</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">T,&nbsp;U,&nbsp;</SPAN><SPAN style="COLOR: #0000ff">false</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000"><BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;U&nbsp;result;<BR>};<BR><BR><BR><BR>template&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000">&nbsp;T,&nbsp;</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000">&nbsp;U</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #0000ff">struct</SPAN><SPAN style="COLOR: #000000">&nbsp;Type<BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;typename&nbsp;BigType</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">T,&nbsp;U,&nbsp;(</SPAN><SPAN style="COLOR: #0000ff">sizeof</SPAN><SPAN style="COLOR: #000000">(T)&nbsp;</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">sizeof</SPAN><SPAN style="COLOR: #000000">(U))</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">::result&nbsp;BigType;<BR>};<BR><BR>template&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000">&nbsp;T</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #0000ff">struct</SPAN><SPAN style="COLOR: #000000">&nbsp;Type</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">T,&nbsp;</SPAN><SPAN style="COLOR: #0000ff">double</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000"><BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;</SPAN><SPAN style="COLOR: #0000ff">double</SPAN><SPAN style="COLOR: #000000">&nbsp;BigType;<BR>};<BR><BR>template&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000">&nbsp;T</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #0000ff">struct</SPAN><SPAN style="COLOR: #000000">&nbsp;Type</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #0000ff">double</SPAN><SPAN style="COLOR: #000000">,&nbsp;T</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000"><BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;</SPAN><SPAN style="COLOR: #0000ff">double</SPAN><SPAN style="COLOR: #000000">&nbsp;BigType;<BR>};<BR><BR><BR>template&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000">&nbsp;T</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #0000ff">struct</SPAN><SPAN style="COLOR: #000000">&nbsp;Type</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">T,&nbsp;</SPAN><SPAN style="COLOR: #0000ff">float</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000"><BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;</SPAN><SPAN style="COLOR: #0000ff">float</SPAN><SPAN style="COLOR: #000000">&nbsp;BigType;<BR>};<BR><BR>template&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000">&nbsp;T</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #0000ff">struct</SPAN><SPAN style="COLOR: #000000">&nbsp;Type</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #0000ff">float</SPAN><SPAN style="COLOR: #000000">,&nbsp;T</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000"><BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;</SPAN><SPAN style="COLOR: #0000ff">float</SPAN><SPAN style="COLOR: #000000">&nbsp;BigType;<BR>};<BR><BR><BR>template&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;&gt;</SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #0000ff">struct</SPAN><SPAN style="COLOR: #000000">&nbsp;Type</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #0000ff">double</SPAN><SPAN style="COLOR: #000000">,&nbsp;</SPAN><SPAN style="COLOR: #0000ff">float</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000"><BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;</SPAN><SPAN style="COLOR: #0000ff">double</SPAN><SPAN style="COLOR: #000000">&nbsp;BigType;<BR>};<BR><BR>template&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;&gt;</SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #0000ff">struct</SPAN><SPAN style="COLOR: #000000">&nbsp;Type</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #0000ff">float</SPAN><SPAN style="COLOR: #000000">,&nbsp;</SPAN><SPAN style="COLOR: #0000ff">double</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000"><BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;</SPAN><SPAN style="COLOR: #0000ff">double</SPAN><SPAN style="COLOR: #000000">&nbsp;BigType;<BR>};<BR><BR><BR><BR>template&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000">&nbsp;T,&nbsp;</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000">&nbsp;U</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000"><BR>typename&nbsp;Type</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">T,&nbsp;U</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">::BigType&nbsp;MaX&nbsp;(</SPAN><SPAN style="COLOR: #0000ff">const</SPAN><SPAN style="COLOR: #000000">&nbsp;T</SPAN><SPAN style="COLOR: #000000">&amp;</SPAN><SPAN style="COLOR: #000000">&nbsp;t,&nbsp;</SPAN><SPAN style="COLOR: #0000ff">const</SPAN><SPAN style="COLOR: #000000">&nbsp;U</SPAN><SPAN style="COLOR: #000000">&amp;</SPAN><SPAN style="COLOR: #000000">&nbsp;u)<BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;typename&nbsp;Type</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">T,&nbsp;U</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">::BigType&nbsp;ResultType;<BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">return</SPAN><SPAN style="COLOR: #000000">&nbsp;ResultType(t&nbsp;</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">&nbsp;u&nbsp;</SPAN><SPAN style="COLOR: #000000">?</SPAN><SPAN style="COLOR: #000000">&nbsp;t&nbsp;:&nbsp;u);&nbsp;</SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000">&nbsp;原为return&nbsp;(ResultType)t&nbsp;&gt;&nbsp;u&nbsp;?&nbsp;t&nbsp;:&nbsp;u;</SPAN><SPAN style="COLOR: #008000"><BR></SPAN><SPAN style="COLOR: #000000">}<BR><BR></SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&nbsp;main&nbsp;()<BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;assert&nbsp;(typeid(MaX(</SPAN><SPAN style="COLOR: #000000">1</SPAN><SPAN style="COLOR: #000000">,&nbsp;</SPAN><SPAN style="COLOR: #000000">2</SPAN><SPAN style="COLOR: #000000">))&nbsp;</SPAN><SPAN style="COLOR: #000000">==</SPAN><SPAN style="COLOR: #000000">&nbsp;typeid(</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">));<BR>&nbsp;&nbsp;&nbsp;&nbsp;assert&nbsp;(MaX(</SPAN><SPAN style="COLOR: #000000">1</SPAN><SPAN style="COLOR: #000000">,&nbsp;</SPAN><SPAN style="COLOR: #000000">2</SPAN><SPAN style="COLOR: #000000">)&nbsp;</SPAN><SPAN style="COLOR: #000000">==</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">2</SPAN><SPAN style="COLOR: #000000">);<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;assert&nbsp;(typeid(MaX(</SPAN><SPAN style="COLOR: #000000">1</SPAN><SPAN style="COLOR: #000000">,&nbsp;</SPAN><SPAN style="COLOR: #000000">2.5</SPAN><SPAN style="COLOR: #000000">))&nbsp;</SPAN><SPAN style="COLOR: #000000">==</SPAN><SPAN style="COLOR: #000000">&nbsp;typeid(</SPAN><SPAN style="COLOR: #0000ff">double</SPAN><SPAN style="COLOR: #000000">));<BR>&nbsp;&nbsp;&nbsp;&nbsp;assert&nbsp;(MaX(</SPAN><SPAN style="COLOR: #000000">1</SPAN><SPAN style="COLOR: #000000">,&nbsp;</SPAN><SPAN style="COLOR: #000000">2.5</SPAN><SPAN style="COLOR: #000000">)&nbsp;</SPAN><SPAN style="COLOR: #000000">==</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">2.5</SPAN><SPAN style="COLOR: #000000">);<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;assert&nbsp;(typeid(MaX(</SPAN><SPAN style="COLOR: #000000">1</SPAN><SPAN style="COLOR: #000000">,&nbsp;(</SPAN><SPAN style="COLOR: #0000ff">float</SPAN><SPAN style="COLOR: #000000">)</SPAN><SPAN style="COLOR: #000000">2.5</SPAN><SPAN style="COLOR: #000000">))&nbsp;</SPAN><SPAN style="COLOR: #000000">==</SPAN><SPAN style="COLOR: #000000">&nbsp;typeid(</SPAN><SPAN style="COLOR: #0000ff">float</SPAN><SPAN style="COLOR: #000000">));<BR>&nbsp;&nbsp;&nbsp;&nbsp;assert&nbsp;(MaX(</SPAN><SPAN style="COLOR: #000000">1</SPAN><SPAN style="COLOR: #000000">,&nbsp;(</SPAN><SPAN style="COLOR: #0000ff">float</SPAN><SPAN style="COLOR: #000000">)</SPAN><SPAN style="COLOR: #000000">2.5</SPAN><SPAN style="COLOR: #000000">)&nbsp;</SPAN><SPAN style="COLOR: #000000">==</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">2.5</SPAN><SPAN style="COLOR: #000000">);<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;assert&nbsp;(typeid(MaX((</SPAN><SPAN style="COLOR: #0000ff">double</SPAN><SPAN style="COLOR: #000000">)</SPAN><SPAN style="COLOR: #000000">2</SPAN><SPAN style="COLOR: #000000">,&nbsp;(</SPAN><SPAN style="COLOR: #0000ff">float</SPAN><SPAN style="COLOR: #000000">)</SPAN><SPAN style="COLOR: #000000">2.5</SPAN><SPAN style="COLOR: #000000">))&nbsp;</SPAN><SPAN style="COLOR: #000000">==</SPAN><SPAN style="COLOR: #000000">&nbsp;typeid(</SPAN><SPAN style="COLOR: #0000ff">double</SPAN><SPAN style="COLOR: #000000">));<BR>&nbsp;&nbsp;&nbsp;&nbsp;assert&nbsp;(MaX((</SPAN><SPAN style="COLOR: #0000ff">double</SPAN><SPAN style="COLOR: #000000">)</SPAN><SPAN style="COLOR: #000000">2</SPAN><SPAN style="COLOR: #000000">,&nbsp;(</SPAN><SPAN style="COLOR: #0000ff">float</SPAN><SPAN style="COLOR: #000000">)</SPAN><SPAN style="COLOR: #000000">2.5</SPAN><SPAN style="COLOR: #000000">)&nbsp;</SPAN><SPAN style="COLOR: #000000">==</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">2.5</SPAN><SPAN style="COLOR: #000000">);<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;assert&nbsp;(typeid(MaX((</SPAN><SPAN style="COLOR: #0000ff">long</SPAN><SPAN style="COLOR: #000000">)</SPAN><SPAN style="COLOR: #000000">2</SPAN><SPAN style="COLOR: #000000">,&nbsp;(</SPAN><SPAN style="COLOR: #0000ff">float</SPAN><SPAN style="COLOR: #000000">)</SPAN><SPAN style="COLOR: #000000">2.5</SPAN><SPAN style="COLOR: #000000">))&nbsp;</SPAN><SPAN style="COLOR: #000000">==</SPAN><SPAN style="COLOR: #000000">&nbsp;typeid(</SPAN><SPAN style="COLOR: #0000ff">float</SPAN><SPAN style="COLOR: #000000">));<BR>&nbsp;&nbsp;&nbsp;&nbsp;assert&nbsp;(MaX((</SPAN><SPAN style="COLOR: #0000ff">long</SPAN><SPAN style="COLOR: #000000">)</SPAN><SPAN style="COLOR: #000000">2</SPAN><SPAN style="COLOR: #000000">,&nbsp;(</SPAN><SPAN style="COLOR: #0000ff">float</SPAN><SPAN style="COLOR: #000000">)</SPAN><SPAN style="COLOR: #000000">2.5</SPAN><SPAN style="COLOR: #000000">)&nbsp;</SPAN><SPAN style="COLOR: #000000">==</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">2.5</SPAN><SPAN style="COLOR: #000000">);<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;assert&nbsp;(typeid(MaX((</SPAN><SPAN style="COLOR: #0000ff">long</SPAN><SPAN style="COLOR: #000000">)</SPAN><SPAN style="COLOR: #000000">2</SPAN><SPAN style="COLOR: #000000">,&nbsp;(</SPAN><SPAN style="COLOR: #0000ff">short</SPAN><SPAN style="COLOR: #000000">)</SPAN><SPAN style="COLOR: #000000">2</SPAN><SPAN style="COLOR: #000000">))&nbsp;</SPAN><SPAN style="COLOR: #000000">==</SPAN><SPAN style="COLOR: #000000">&nbsp;typeid(</SPAN><SPAN style="COLOR: #0000ff">long</SPAN><SPAN style="COLOR: #000000">));<BR>&nbsp;&nbsp;&nbsp;&nbsp;assert&nbsp;(MaX((</SPAN><SPAN style="COLOR: #0000ff">long</SPAN><SPAN style="COLOR: #000000">)</SPAN><SPAN style="COLOR: #000000">2</SPAN><SPAN style="COLOR: #000000">,&nbsp;(</SPAN><SPAN style="COLOR: #0000ff">short</SPAN><SPAN style="COLOR: #000000">)</SPAN><SPAN style="COLOR: #000000">2</SPAN><SPAN style="COLOR: #000000">)&nbsp;</SPAN><SPAN style="COLOR: #000000">==</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">2</SPAN><SPAN style="COLOR: #000000">);<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;assert&nbsp;(typeid(MaX((</SPAN><SPAN style="COLOR: #0000ff">float</SPAN><SPAN style="COLOR: #000000">)</SPAN><SPAN style="COLOR: #000000">2</SPAN><SPAN style="COLOR: #000000">,&nbsp;(__int64)</SPAN><SPAN style="COLOR: #000000">2</SPAN><SPAN style="COLOR: #000000">))&nbsp;</SPAN><SPAN style="COLOR: #000000">==</SPAN><SPAN style="COLOR: #000000">&nbsp;typeid(</SPAN><SPAN style="COLOR: #0000ff">float</SPAN><SPAN style="COLOR: #000000">));<BR>&nbsp;&nbsp;&nbsp;&nbsp;assert&nbsp;(MaX((</SPAN><SPAN style="COLOR: #0000ff">float</SPAN><SPAN style="COLOR: #000000">)</SPAN><SPAN style="COLOR: #000000">2</SPAN><SPAN style="COLOR: #000000">,&nbsp;(__int64)</SPAN><SPAN style="COLOR: #000000">2</SPAN><SPAN style="COLOR: #000000">)&nbsp;</SPAN><SPAN style="COLOR: #000000">==</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">2</SPAN><SPAN style="COLOR: #000000">);<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;assert&nbsp;(std::</SPAN><SPAN style="COLOR: #0000ff">string</SPAN><SPAN style="COLOR: #000000">(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">hello</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">)&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">world</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">);<BR>&nbsp;&nbsp;&nbsp;&nbsp;assert&nbsp;(typeid(MaX(std::</SPAN><SPAN style="COLOR: #0000ff">string</SPAN><SPAN style="COLOR: #000000">(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">hello</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">),&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">world</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">))&nbsp;</SPAN><SPAN style="COLOR: #000000">==</SPAN><SPAN style="COLOR: #000000">&nbsp;typeid(std::</SPAN><SPAN style="COLOR: #0000ff">string</SPAN><SPAN style="COLOR: #000000">));<BR>&nbsp;&nbsp;&nbsp;&nbsp;assert&nbsp;(MaX(std::</SPAN><SPAN style="COLOR: #0000ff">string</SPAN><SPAN style="COLOR: #000000">(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">hello</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">),&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">world</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">)&nbsp;</SPAN><SPAN style="COLOR: #000000">==</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">world</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">);<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;assert&nbsp;(typeid(MaX(std::</SPAN><SPAN style="COLOR: #0000ff">string</SPAN><SPAN style="COLOR: #000000">(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">world</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">),&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">hello</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">))&nbsp;</SPAN><SPAN style="COLOR: #000000">==</SPAN><SPAN style="COLOR: #000000">&nbsp;typeid(std::</SPAN><SPAN style="COLOR: #0000ff">string</SPAN><SPAN style="COLOR: #000000">));<BR>&nbsp;&nbsp;&nbsp;&nbsp;assert&nbsp;(MaX(std::</SPAN><SPAN style="COLOR: #0000ff">string</SPAN><SPAN style="COLOR: #000000">(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">hello</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">),&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">world</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">)&nbsp;</SPAN><SPAN style="COLOR: #000000">==</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">world</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">);<BR><BR><BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000">&nbsp;测试数，需定义在循环外，防止编译器优化掉无意义的循环</SPAN><SPAN style="COLOR: #008000"><BR></SPAN><SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;__int64&nbsp;test&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">0</SPAN><SPAN style="COLOR: #000000">;<BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">long</SPAN><SPAN style="COLOR: #000000">&nbsp;start&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;GetTickCount();<BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">for</SPAN><SPAN style="COLOR: #000000">&nbsp;(</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&nbsp;i</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">0</SPAN><SPAN style="COLOR: #000000">;&nbsp;i</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">1000000000</SPAN><SPAN style="COLOR: #000000">;&nbsp;</SPAN><SPAN style="COLOR: #000000">++</SPAN><SPAN style="COLOR: #000000">i)<BR>&nbsp;&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;test&nbsp;</SPAN><SPAN style="COLOR: #000000">+=</SPAN><SPAN style="COLOR: #000000">&nbsp;MaX(i,&nbsp;(__int64)i);<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000">&nbsp;test必须被使用，否则编译器视为无用数据，会被优化掉</SPAN><SPAN style="COLOR: #008000"><BR></SPAN><SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;std::cout&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;&lt;</SPAN><SPAN style="COLOR: #000000">&nbsp;test&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;&lt;</SPAN><SPAN style="COLOR: #000000">&nbsp;std::endl;<BR>&nbsp;&nbsp;&nbsp;&nbsp;std::cout&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;&lt;</SPAN><SPAN style="COLOR: #000000">&nbsp;(GetTickCount()&nbsp;</SPAN><SPAN style="COLOR: #000000">-</SPAN><SPAN style="COLOR: #000000">&nbsp;start)&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;&lt;</SPAN><SPAN style="COLOR: #000000">&nbsp;std::endl;<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;test&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">0</SPAN><SPAN style="COLOR: #000000">;<BR>&nbsp;&nbsp;&nbsp;&nbsp;start&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;GetTickCount();<BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">for</SPAN><SPAN style="COLOR: #000000">&nbsp;(</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&nbsp;i</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">0</SPAN><SPAN style="COLOR: #000000">;&nbsp;i</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">1000000000</SPAN><SPAN style="COLOR: #000000">;&nbsp;</SPAN><SPAN style="COLOR: #000000">++</SPAN><SPAN style="COLOR: #000000">i)<BR>&nbsp;&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;test&nbsp;</SPAN><SPAN style="COLOR: #000000">+=</SPAN><SPAN style="COLOR: #000000">&nbsp;max(i,&nbsp;(__int64)i);<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;std::cout&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;&lt;</SPAN><SPAN style="COLOR: #000000">&nbsp;test&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;&lt;</SPAN><SPAN style="COLOR: #000000">&nbsp;std::endl;<BR>&nbsp;&nbsp;&nbsp;&nbsp;std::cout&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;&lt;</SPAN><SPAN style="COLOR: #000000">&nbsp;(GetTickCount()&nbsp;</SPAN><SPAN style="COLOR: #000000">-</SPAN><SPAN style="COLOR: #000000">&nbsp;start)&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;&lt;</SPAN><SPAN style="COLOR: #000000">&nbsp;std::endl;<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">return</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">0</SPAN><SPAN style="COLOR: #000000">;<BR>}</SPAN></DIV><img src ="http://www.cppblog.com/cpunion/aggbug/1692.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cpunion/" target="_blank">qiezi</a> 2005-12-12 10:45 <a href="http://www.cppblog.com/cpunion/archive/2005/12/12/1692.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>为C＋＋实现一个IDL　（五）</title><link>http://www.cppblog.com/cpunion/archive/2005/09/28/481.html</link><dc:creator>qiezi</dc:creator><author>qiezi</author><pubDate>Wed, 28 Sep 2005 14:57:00 GMT</pubDate><guid>http://www.cppblog.com/cpunion/archive/2005/09/28/481.html</guid><wfw:comment>http://www.cppblog.com/cpunion/comments/481.html</wfw:comment><comments>http://www.cppblog.com/cpunion/archive/2005/09/28/481.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.cppblog.com/cpunion/comments/commentRss/481.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/cpunion/services/trackbacks/481.html</trackback:ping><description><![CDATA[本篇没什么清晰的目的，只是解释一下前面的几个问题，并提出一些新的目标。<BR><BR>在“asgard项目遗留问题”中，我简单提到了几个问题，并且想了一些解决方案。<BR><BR>其中，最首要解决的是第2条“服务对象的大小”和第5条“全局元信息”，这2条将影响到调用机制、call对象的生成。一个调用将生成一个call对象，由线程池来处理，同步调用将由异步调用来模拟。<BR><BR>在call对象中，保存了所有in/out参数的包装对象。当处理同步调用时，由于out参数可能是一个栈上对象（或简单类型，这里统称对象），所以需要另一个包装类——outret模板类，它保存out参数的引用。<BR><BR>当同步调用发生时，生成一个call对象（当然out参数的引用已经包含在里面），把这个call对象交给线程池处理，调用的线程阻塞等待调用结束后被唤醒，这就是所谓的异步调用模拟同步调用。由于异步调用被包装起来了，所以在调用者看来跟同步调用没什么区别。当然这个动作并非必要，完全可以不使用模拟，而采用真正的同步调用，只是看到ICE是这么实现的，心痒痒而已。<BR><BR><BR>asgard的目标是把现有的系统功能包装成为服务，所以在通用方面我考虑得比较多。<BR><BR>比如服务端要开放下面这样一个服务：<BR><BR>
<DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><SPAN style="COLOR: #000000">service&nbsp;StringService<BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;Method&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #0000ff">string</SPAN><SPAN style="COLOR: #000000">(inout</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #0000ff">string</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">,&nbsp;</SPAN><SPAN style="COLOR: #0000ff">in</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #0000ff">string</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">)</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">&nbsp;strcat;<BR>&nbsp;&nbsp;&nbsp;&nbsp;Method&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #0000ff">string</SPAN><SPAN style="COLOR: #000000">(inout</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #0000ff">string</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">,&nbsp;</SPAN><SPAN style="COLOR: #0000ff">in</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #0000ff">string</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">,&nbsp;</SPAN><SPAN style="COLOR: #0000ff">in</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #0000ff">uint</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">)</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">&nbsp;strncat;<BR>};</SPAN></DIV><BR>并且把C标准库中的strcat和strncat作为这2个方法的实现。<BR><BR>看一下存在哪些问题？<BR><BR>1、函数第1个参数如果直接映射为string，在服务端将出现缓冲区溢出。<BR><BR>2、C标准库中的strcat返回值是一个指针，它指向strcat的第一个参数（搞这个标准库的人是不是没想过这个返回值多么没用啊？？直接返回一个操作的长度不是更好？），在服务端发回客户端时，这个并不需要被发回来，因为strcat的第1个参数已经能带回操作后的内容了。<BR><BR>3、strncat的第3个参数表示第1个缓冲区参数的长度，如果能把它和第1个参数合起来用一个buffer对象表示，就能省事了。<BR><BR>理想情况下，我们的服务对象这样来写：<BR><BR>
<DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><SPAN style="COLOR: #000000">service&nbsp;StringService<BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;Method&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">(inout</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">&nbsp;buffer</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #0000ff">char</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">,&nbsp;</SPAN><SPAN style="COLOR: #0000ff">in</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #0000ff">string</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">)</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">&nbsp;strcat;<BR>&nbsp;&nbsp;&nbsp;&nbsp;Method&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">(inout</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">&nbsp;buffer</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #0000ff">char</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">,&nbsp;</SPAN><SPAN style="COLOR: #0000ff">in</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #0000ff">string</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">)</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">&nbsp;strncat;<BR>};</SPAN></DIV><BR>我们的目的是把老的代码包装成新鲜时髦的服务，当然不用保留老式代码中的指针，以及使用指针和长度2个值来表示一个缓冲区的做法。buffer类在构造时要接受一个size_t参数，指定缓冲区的大小。<BR><BR>这在服务端将产生映射问题，由于这个Method定义的形式和C标准库中的函数形式不一致。<BR><BR>我想应该去实现一个适配器模板类，比如：<BR><BR>
<DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><SPAN style="COLOR: #0000ff">this</SPAN><SPAN style="COLOR: #000000">-&gt;</SPAN><SPAN style="COLOR: #000000">strcat.setFunction&nbsp;(adapter</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #0000ff">char</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000">(</SPAN><SPAN style="COLOR: #0000ff">char</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000">,&nbsp;</SPAN><SPAN style="COLOR: #0000ff">const</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">char</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000">),&nbsp;convert</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">,&nbsp;</SPAN><SPAN style="COLOR: #000000">0</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">(inout</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">&nbsp;buffer</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #0000ff">char</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">,&nbsp;</SPAN><SPAN style="COLOR: #0000ff">in</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #0000ff">string</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">)</SPAN><SPAN style="COLOR: #000000">&gt; (::strcat)</SPAN><SPAN style="COLOR: #000000">);<BR><BR></SPAN><SPAN style="COLOR: #0000ff">this</SPAN><SPAN style="COLOR: #000000">-&gt;</SPAN><SPAN style="COLOR: #000000">strncat.setFunction&nbsp;(adapter</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #0000ff">char</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000">(</SPAN><SPAN style="COLOR: #0000ff">char</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000">,&nbsp;</SPAN><SPAN style="COLOR: #0000ff">const</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">char</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000">,&nbsp;size_t),&nbsp;convert</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">,&nbsp;</SPAN><SPAN style="COLOR: #000000">0</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">(inout</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">&nbsp;buffer</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #0000ff">char</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">,&nbsp;</SPAN><SPAN style="COLOR: #0000ff">in</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #0000ff">string</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">,&nbsp;length</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #0000ff">in</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #0000ff">uint</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">,&nbsp;</SPAN><SPAN style="COLOR: #000000">1</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">)</SPAN><SPAN style="COLOR: #000000">&gt; (::strncat)</SPAN><SPAN style="COLOR: #000000">);</SPAN></DIV><BR>convert&lt;void, 0&gt;表示把第0个参数（这里指返回值）转成void类型，length&lt;in&lt;uint&gt;, 1&gt;表示这个参数类型是int&lt;uint&gt;，它是从第1个参数中提取的长度，大致就是使用这种规则，语法可能以后会有变动。<BR><BR>这点内容是我几个月前就在考虑的，也是我想做这个项目的动机，不过直到最近一段时间才从可行性方面仔细考虑。<BR><BR>通过前面几个模板的练习，现在已经大致知道哪些东西是可以用模板做出来，哪些不能使用模板，这应该是最大的收获了。很多东西单靠模板或是虚函数都不好完成，但结合起来就能产生意想不到的效果。<BR><BR>
<HR>
<BR>又仔细想了一下，上面的代码应该还可以修改简化：<BR><BR>
<DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><SPAN style="COLOR: #0000ff">this</SPAN><SPAN style="COLOR: #000000">-&gt;</SPAN><SPAN style="COLOR: #000000">strcat.setFunction&nbsp;(adapter</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">convert</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">,&nbsp;</SPAN><SPAN style="COLOR: #000000">0</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">(inout</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">&nbsp;buffer</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #0000ff">char</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">,&nbsp;</SPAN><SPAN style="COLOR: #0000ff">in</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #0000ff">string</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">)</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">&nbsp;( ) (::strcat));<BR><BR></SPAN><SPAN style="COLOR: #0000ff">this</SPAN><SPAN style="COLOR: #000000">-&gt;</SPAN><SPAN style="COLOR: #000000">strncat.setFunction&nbsp;(adapter</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">convert</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">,&nbsp;</SPAN><SPAN style="COLOR: #000000">0</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">(inout</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">&nbsp;buffer</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #0000ff">char</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">,&nbsp;</SPAN><SPAN style="COLOR: #0000ff">in</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #0000ff">string</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">,&nbsp;length</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #0000ff">in</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #0000ff">uint</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">,&nbsp;</SPAN><SPAN style="COLOR: #000000">1</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">)</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">&nbsp;( ) (::strncat));</SPAN></DIV><BR>使用一个仿函数来做，函数指针的类型可以从operator ()的参数（模板参数）中推导出来。<img src ="http://www.cppblog.com/cpunion/aggbug/481.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cpunion/" target="_blank">qiezi</a> 2005-09-28 22:57 <a href="http://www.cppblog.com/cpunion/archive/2005/09/28/481.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C＋＋实现简单的类型库</title><link>http://www.cppblog.com/cpunion/archive/2005/09/26/435.html</link><dc:creator>qiezi</dc:creator><author>qiezi</author><pubDate>Mon, 26 Sep 2005 09:31:00 GMT</pubDate><guid>http://www.cppblog.com/cpunion/archive/2005/09/26/435.html</guid><wfw:comment>http://www.cppblog.com/cpunion/comments/435.html</wfw:comment><comments>http://www.cppblog.com/cpunion/archive/2005/09/26/435.html#Feedback</comments><slash:comments>9</slash:comments><wfw:commentRss>http://www.cppblog.com/cpunion/comments/commentRss/435.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/cpunion/services/trackbacks/435.html</trackback:ping><description><![CDATA[很久以前看到有人问“如何在C＋＋中实现动态加载类”时，简单地做了一个。<BR><BR>不过当时没有去考虑动态加载DLL的情况。<BR><BR>今天在<A href="mailto:cpp@codingnow.com">cpp@codingnow.com</A>中也有人问到这个问题，就把它给做完了。<BR><BR>当然只是简单地做到了“从全局类型库中，根据类名创建实例，支持动态DLL加载”，说得更明白点：<BR><BR>在应用程序App1中，向全局类型库中注册一个类型"Test"，在另一个隐式链接的DLL中（即App1一启动就加载的DLL），向全局类型库中注册另外几个类型。这时可以在App1中通过类型的名字生成实例。<BR><BR>在另一个显式加载的DLL中（即调用LoadLibrary加载），向全局类型库中注册其它几个类型。这时通过LoadLibrary加载这个DLL，就可以生成这几个类型的实例了。<BR><BR>这地方不能上传文件，就把代码贴一点吧：<BR><BR>typelib.h文件：<BR><BR>
<DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><SPAN style="COLOR: #000000">#ifndef&nbsp;__TYPE_LIB_H__<BR></SPAN><SPAN style="COLOR: #0000ff">#define</SPAN><SPAN style="COLOR: #000000">&nbsp;__TYPE_LIB_H__</SPAN><SPAN style="COLOR: #000000"><BR><BR>typedef&nbsp;</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000">(</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000">CREATE_FUNC)();<BR>typedef&nbsp;</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">(</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000">RELEASE_FUNC)(</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000">);<BR><BR></SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">&nbsp;regtype&nbsp;(</SPAN><SPAN style="COLOR: #0000ff">const</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">char</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000">&nbsp;name,&nbsp;CREATE_FUNC&nbsp;cfunc,&nbsp;RELEASE_FUNC&nbsp;rfunc);<BR><BR></SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000">&nbsp;createObject&nbsp;(</SPAN><SPAN style="COLOR: #0000ff">const</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">char</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000">&nbsp;name);<BR><BR></SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">&nbsp;releaseObject&nbsp;(</SPAN><SPAN style="COLOR: #0000ff">const</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">char</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000">&nbsp;name,&nbsp;</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000">&nbsp;p);<BR><BR></SPAN><SPAN style="COLOR: #0000ff">struct</SPAN><SPAN style="COLOR: #000000">&nbsp;ITestInterface<BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">virtual</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">~</SPAN><SPAN style="COLOR: #000000">ITestInterface&nbsp;()&nbsp;{}<BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">virtual</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">&nbsp;print&nbsp;()&nbsp;</SPAN><SPAN style="COLOR: #0000ff">const</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">0</SPAN><SPAN style="COLOR: #000000">;<BR>};<BR><BR>template&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000">&nbsp;T</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000">&nbsp;create&nbsp;()<BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">return</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">new</SPAN><SPAN style="COLOR: #000000">&nbsp;T;<BR>}<BR><BR>template&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000">&nbsp;T</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">&nbsp;release&nbsp;(</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000">&nbsp;p)<BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;delete&nbsp;(T</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000">)p;<BR>}<BR><BR></SPAN><SPAN style="COLOR: #0000ff">#endif</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000">&nbsp;__TYPE_LIB_H__</SPAN></DIV><BR>typelib.cpp文件：<BR><BR>
<DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><SPAN style="COLOR: #000000">#include&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">typelib.h</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000"><BR><BR>#include&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #0000ff">string</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000"><BR>#include&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">map</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #0000ff">using</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">namespace</SPAN><SPAN style="COLOR: #000000">&nbsp;std;<BR><BR></SPAN><SPAN style="COLOR: #0000ff">namespace</SPAN><SPAN style="COLOR: #000000">&nbsp;TypeRegistry<BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">static</SPAN><SPAN style="COLOR: #000000">&nbsp;map&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">string</SPAN><SPAN style="COLOR: #000000">,&nbsp;pair</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">CREATE_FUNC,&nbsp;RELEASE_FUNC</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">&nbsp;&nbsp;types_info;<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;template&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000">&nbsp;T</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000"><BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">&nbsp;regType&nbsp;(</SPAN><SPAN style="COLOR: #0000ff">const</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">string</SPAN><SPAN style="COLOR: #000000">&amp;</SPAN><SPAN style="COLOR: #000000">&nbsp;name)<BR>&nbsp;&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;types_info.insert&nbsp;(make_pair(name,&nbsp;make_pair(create</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">T</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">,&nbsp;release</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">T</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">)));<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR>}<BR><BR></SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">&nbsp;regtype&nbsp;(</SPAN><SPAN style="COLOR: #0000ff">const</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">char</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000">&nbsp;name,&nbsp;CREATE_FUNC&nbsp;cfunc,&nbsp;RELEASE_FUNC&nbsp;rfunc)<BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;TypeRegistry::types_info.insert&nbsp;(make_pair(name,&nbsp;make_pair(cfunc,&nbsp;rfunc)));<BR>}<BR><BR></SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000">&nbsp;createObject&nbsp;(</SPAN><SPAN style="COLOR: #0000ff">const</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">char</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000">&nbsp;name)<BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;map&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">string</SPAN><SPAN style="COLOR: #000000">,&nbsp;pair</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">CREATE_FUNC,&nbsp;RELEASE_FUNC</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">::const_iterator&nbsp;iter;<BR>&nbsp;&nbsp;&nbsp;&nbsp;iter&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;TypeRegistry::types_info.find&nbsp;(name);<BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">if</SPAN><SPAN style="COLOR: #000000">&nbsp;(iter&nbsp;</SPAN><SPAN style="COLOR: #000000">!=</SPAN><SPAN style="COLOR: #000000">&nbsp;TypeRegistry::types_info.end&nbsp;())<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">return</SPAN><SPAN style="COLOR: #000000">&nbsp;(</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000">iter</SPAN><SPAN style="COLOR: #000000">-&gt;</SPAN><SPAN style="COLOR: #000000">second.first)();<BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">return</SPAN><SPAN style="COLOR: #000000">&nbsp;NULL;<BR>}<BR><BR></SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">&nbsp;releaseObject&nbsp;(</SPAN><SPAN style="COLOR: #0000ff">const</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">char</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000">&nbsp;name,&nbsp;</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000">&nbsp;p)<BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;map&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">string</SPAN><SPAN style="COLOR: #000000">,&nbsp;pair</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">CREATE_FUNC,&nbsp;RELEASE_FUNC</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">::const_iterator&nbsp;iter;<BR>&nbsp;&nbsp;&nbsp;&nbsp;iter&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;TypeRegistry::types_info.find&nbsp;(name);<BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">if</SPAN><SPAN style="COLOR: #000000">&nbsp;(iter&nbsp;</SPAN><SPAN style="COLOR: #000000">!=</SPAN><SPAN style="COLOR: #000000">&nbsp;TypeRegistry::types_info.end&nbsp;())<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000">iter</SPAN><SPAN style="COLOR: #000000">-&gt;</SPAN><SPAN style="COLOR: #000000">second.second)(p);<BR>}</SPAN></DIV><BR>把它编译成静态lib或DLL，就可以使用了。<BR><BR>在那2个为我们提供类型的DLL中，DllMain函数中加入下面的代码：<BR><BR>
<DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000">&nbsp;FirstTest和SecondTest是2个类名</SPAN><SPAN style="COLOR: #008000"><BR></SPAN><SPAN style="COLOR: #000000">regtype(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">FirstTest</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">,&nbsp;create</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">FirstTest</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">,&nbsp;release</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">FirstTest</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">);<BR>regtype(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">FirstTest</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">,&nbsp;create</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">SecondTest</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">,&nbsp;release</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">SecondTest</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">);</SPAN></DIV><BR>就可以向全局类型库中注册类型。注意在类型库中是没有保存类信息的，所以最好是使用单根类库来做。<BR><BR>下面是一点测试代码：<BR><BR>
<DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&nbsp;main()<BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000">&nbsp;程序启动时注册类型。<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000">&nbsp;实际上启动时就加载了另一个动态链接库，那里面有3个类型，所以现在有4个类型</SPAN><SPAN style="COLOR: #008000"><BR></SPAN><SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;regtype&nbsp;(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">MyTest</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">,&nbsp;create</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">MyTest</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">,&nbsp;release</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">MyTest</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">while</SPAN><SPAN style="COLOR: #000000">&nbsp;(</SPAN><SPAN style="COLOR: #000000">1</SPAN><SPAN style="COLOR: #000000">)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">string</SPAN><SPAN style="COLOR: #000000">&nbsp;class_name;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cin&nbsp;</SPAN><SPAN style="COLOR: #000000">&gt;&gt;</SPAN><SPAN style="COLOR: #000000">&nbsp;class_name;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">if</SPAN><SPAN style="COLOR: #000000">&nbsp;(class_name&nbsp;</SPAN><SPAN style="COLOR: #000000">==</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">q</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">break</SPAN><SPAN style="COLOR: #000000">;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000">&nbsp;当输入load时，把另一个动态链接库加载进来，那个链接库中有2个类型，现在共有6个类型可用。</SPAN><SPAN style="COLOR: #008000"><BR></SPAN><SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">if</SPAN><SPAN style="COLOR: #000000">&nbsp;(class_name&nbsp;</SPAN><SPAN style="COLOR: #000000">==</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">load</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LoadLibrary(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">typelibdll_test.dll</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">continue</SPAN><SPAN style="COLOR: #000000">;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ITestInterface</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000">&nbsp;test&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;(ITestInterface</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000">)createObject&nbsp;(class_name.c_str());<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">if</SPAN><SPAN style="COLOR: #000000">&nbsp;(</SPAN><SPAN style="COLOR: #000000">!</SPAN><SPAN style="COLOR: #000000">test)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cout&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;&lt;</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">This&nbsp;type&nbsp;not&nbsp;found</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;&lt;</SPAN><SPAN style="COLOR: #000000">&nbsp;endl;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">continue</SPAN><SPAN style="COLOR: #000000">;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;test</SPAN><SPAN style="COLOR: #000000">-&gt;</SPAN><SPAN style="COLOR: #000000">print&nbsp;();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;releaseObject&nbsp;(class_name.c_str(),&nbsp;test);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">return</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">0</SPAN><SPAN style="COLOR: #000000">;<BR>}<BR></SPAN></DIV><BR>还有一个没考虑的地方，就是没有给它加锁，因为有可能在一个线程中加载一个DLL。<BR><BR>不过我还有些怀疑这东西是否真的有用？<img src ="http://www.cppblog.com/cpunion/aggbug/435.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cpunion/" target="_blank">qiezi</a> 2005-09-26 17:31 <a href="http://www.cppblog.com/cpunion/archive/2005/09/26/435.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>asgard项目遗留问题　（2005-09-27更新）</title><link>http://www.cppblog.com/cpunion/archive/2005/09/24/416.html</link><dc:creator>qiezi</dc:creator><author>qiezi</author><pubDate>Sat, 24 Sep 2005 09:00:00 GMT</pubDate><guid>http://www.cppblog.com/cpunion/archive/2005/09/24/416.html</guid><wfw:comment>http://www.cppblog.com/cpunion/comments/416.html</wfw:comment><comments>http://www.cppblog.com/cpunion/archive/2005/09/24/416.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/cpunion/comments/commentRss/416.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/cpunion/services/trackbacks/416.html</trackback:ping><description><![CDATA[asgard项目已经准备了一段时间了，不过有些基本问题还需要考虑，也有一些是新发现的问题，以及自认为比较好的解决办法。<BR><BR>通过第2、第4条的仔细研究，已经渐渐完善、明确了动态部分和静态部分的关系，使得Method包装类所完成的功能渐渐接近于一个函数，而元信息则脱离具体的对象提升到全局（当然还有些小问题没有解决）。<BR><BR><STRONG>1、参数名称的问题。</STRONG><BR><BR>为了与SOAP等基于XML的协议兼容，必须开始就把参数名称考虑在内。<BR><BR>代码经过C＋＋编译器编译以后，类型、变量名称等都不复存在，唯一留下的是RTTI，显然不能解决这个问题。所以只能在定义时把它加入。<BR><BR>
<DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><SPAN style="COLOR: #000000">BEGIN_SERVICE(TestService)<BR>&nbsp;&nbsp;&nbsp;&nbsp;METHOD&nbsp;(</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">(</SPAN><SPAN style="COLOR: #0000ff">in</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">,&nbsp;inout</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #0000ff">string</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">,&nbsp;</SPAN><SPAN style="COLOR: #0000ff">out</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #0000ff">short</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">),&nbsp;method1,&nbsp;index,&nbsp;info,&nbsp;result);<BR>END_SERVICE()</SPAN></DIV><BR>如果使用这种方式，index, info, result分别表示变量名字，在宏里面转成字符串，看起来好像不太舒服，而且宏不支持参数个数变化。<BR><BR>
<DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><SPAN style="COLOR: #000000">BEGIN_SERVICE(TestService)<BR>&nbsp;&nbsp;&nbsp;&nbsp;METHOD&nbsp;(</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">(</SPAN><SPAN style="COLOR: #0000ff">in</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">,&nbsp;inout</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #0000ff">string</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">,&nbsp;</SPAN><SPAN style="COLOR: #0000ff">out</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #0000ff">short</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">),&nbsp;method1,&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">(index,&nbsp;info,&nbsp;result)</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">);<BR>&nbsp;&nbsp;&nbsp;&nbsp;METHOD&nbsp;(</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">(</SPAN><SPAN style="COLOR: #0000ff">in</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">,&nbsp;inout</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #0000ff">string</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">),&nbsp;method2,&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">result(index,&nbsp;info)</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">);<BR>END_SERVICE()</SPAN></DIV><BR>这种可能稍稍舒服一点，在Method构造函数或其它地方解析这个字符串，赋给各个参数。不过它的缺点是把编译期应该检查出来的错误，延迟到运行期。如果在编译期来做，又会使接口描述变得很复杂。<BR><BR>只是为了得到参数的名字，就要增加这么些麻烦。<BR><BR>c++0x只是一个库的标准，估计XTI也不会加入这些特性，而且c++0x很遥远，所以暂时以这种方式来做。<BR><BR><STRONG>暂时的解决办法：</STRONG><BR><BR>
<DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><SPAN style="COLOR: #000000">BEGIN_SERVICE(TestService)<BR>&nbsp;&nbsp;&nbsp;&nbsp;METHOD&nbsp;(</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">(</SPAN><SPAN style="COLOR: #0000ff">in</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">,&nbsp;inout</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #0000ff">string</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">,&nbsp;</SPAN><SPAN style="COLOR: #0000ff">out</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #0000ff">short</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">),&nbsp;method1);<BR>&nbsp;&nbsp;&nbsp;&nbsp;METHOD&nbsp;(</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">(</SPAN><SPAN style="COLOR: #0000ff">in</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">,&nbsp;inout</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #0000ff">string</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">),&nbsp;method2);<BR>&nbsp;&nbsp;&nbsp;&nbsp;BEGIN_SERVICE_DEFINE(TestService)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;METHOD_DEFINE&nbsp;(method1,&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">(index,&nbsp;info,&nbsp;result)</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">,&nbsp;test_func);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;METHOD_DEFINE&nbsp;(method2,&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">result(index,&nbsp;info)</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">,&nbsp;</SPAN><SPAN style="COLOR: #000000">&amp;</SPAN><SPAN style="COLOR: #000000">Test::test_method);<BR>&nbsp;&nbsp;&nbsp;&nbsp;END_SERVICE_DEFINE()<BR>END_SERVICE()</SPAN></DIV><BR>缺点是参数名称中的错误，要延迟到运行期才能解决掉。<BR><BR><STRONG>2、服务对象的大小。<BR></STRONG><BR>如果客户端要调用其中一个方法，生成一个TestService，则构造成本太高，特别是一个服务中有多个方法的时候。一个服务容纳了多个方法，而每个方法包含一个vector，以及各个参数，这还没考虑以后的扩展。<BR><BR>所以应该修改调用方式，让它只只需要生成调用所需的最小（少）对象。<BR><BR>这部分考虑还不成熟，暂时可以不管它，而以方法作为考虑的对象。<BR><BR><STRONG>暂时想到的解决办法：</STRONG><BR><BR>Method对象中的parameters容器和各个参数，只在调用operator ()或async_call时，才真正生成出来。<BR><BR>这样的话，Method对象中仅保存一个空的vector。<BR><BR>甚至这个vector也可以只是一个空指针，当调用那几个函数时，才生成一个。<BR><BR>暂时把这个过程命名为Create On Call(COC)。<BR><BR>COC的好处是显而易见的，每个对象将只有8字节，虚表指针＋数据对象的指针，“数据对象”是实际调用时才生成的对象，包括参数vector容器、回调函数指针（可能由动态生成一个委托对象，以适应广泛类型的回调函数）、对象锁（防止干扰到前一个调用）。初始化成本接近0（虚函数表的初始化忽略不计）。<BR><BR>当调用operator()或async_call时（以下简称CALL），将调用create_parameters虚函数，动态生成一个vector。这样，没有调用到的Method不会象原来一样影响到服务对象的构建性能。<BR><BR>这就要求把Method的“元”信息提到全局，当然更符合“元”的本意，原来由服务对象查询Method以获得“元”信息的过程，现在看来也是不合理的。<BR><BR><STRONG>3、in模板可以省略。</STRONG><BR><BR>in是默认的参数类型，返回值则默认为out类型，这都是不需要明确指定的。<BR><BR><STRONG>解决办法：<BR></STRONG><BR>这个问题是比较好解决的，在InOutTypeTraits模板类中，为各个偏特化版本定义一个type类型，InOutTypeTraits＜T＞::type的类型为in＜T＞，InOutTypes＜in＜T＞＞::type的类型为in＜T＞，InOutTypes＜inout＜T＞＞::type的类型为inout＜T＞，InOutTypes＜out＜T＞＞::type的类型为out＜T＞，InList模板类中进行这种转换。<BR><BR><STRONG>4、异步调用队列。</STRONG><BR><BR>在第2点中介绍道：<BR><BR>每个对象将只有8字节，虚表指针＋数据对象的指针，“数据对象”是实际调用时才生成的对象，包括参数vector容器、回调函数指针（可能由动态生成一个委托对象，以适应广泛类型的回调函数）、对象锁（防止干扰到前一个调用）。初始化成本接近0（虚函数表的初始化忽略不计）。<BR><BR>提到了对象锁，这是一种低效的做法，可以使用异步调用队列来替代它。<BR><BR><STRONG>解决办法：</STRONG><BR><BR>当开始一个调用时，临时生成上面所说的“数据对象”，交由一个调用队列去完成。这时，由于Method对象基本不管理数据，所以它成了一个空壳，作用是保存类型信息。<BR><BR>异步调用最好的实现就是整个系统都由异步调用构成，而同步调用是由异步调用模拟而成。原本打算绕过这种方式，用最简单的方法来做，现在好像又绕回来了。<BR><BR>上面这个做法，很好地把元信息和真实数据分开了，所以打算改成这种结构。<BR><BR>5、全局元信息。<BR><BR>通过第4条的研究，已经使得Method对象成为一个空壳，而“数据对象”在没有调用时又不生成，使得自省结构必须重新做。<BR><BR>考察了java等语言的自省，也打算把元信息的位置提升到全局，而每个Method对象将只保留一个全局元信息的指针，这样应该更自然。<BR><BR><BR>（以后遇到的问题只更新到这个文档中）<img src ="http://www.cppblog.com/cpunion/aggbug/416.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cpunion/" target="_blank">qiezi</a> 2005-09-24 17:00 <a href="http://www.cppblog.com/cpunion/archive/2005/09/24/416.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C++模板的一点资料</title><link>http://www.cppblog.com/cpunion/archive/2005/09/23/407.html</link><dc:creator>qiezi</dc:creator><author>qiezi</author><pubDate>Fri, 23 Sep 2005 04:44:00 GMT</pubDate><guid>http://www.cppblog.com/cpunion/archive/2005/09/23/407.html</guid><wfw:comment>http://www.cppblog.com/cpunion/comments/407.html</wfw:comment><comments>http://www.cppblog.com/cpunion/archive/2005/09/23/407.html#Feedback</comments><slash:comments>5</slash:comments><wfw:commentRss>http://www.cppblog.com/cpunion/comments/commentRss/407.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/cpunion/services/trackbacks/407.html</trackback:ping><description><![CDATA[内容很不完整，仅仅是我自己所知的部分，如有知道详细资料的同学们请一起来完成它，有错误的地方请帮我提出来，等资料多一点我再把文字内容整理一下，我目前就知道这么多了。<BR>下面内容中没有加入年代的，表示我不知道(IUnknown)。。。嘿嘿。<BR><BR><BR><BR>1990年7月，模板被加入C++。<BR><BR>1994年，C++标准委员会在圣迭哥举行的一次会议期间Erwin Unruh展示了一段可以产生质数的代码。这段代码的特别之处在于质数产生于编译期而非运行期。<BR><BR>SGI STL中大量使用Traits模板技术，整个库使用模板技术构建。STL（标准模板库）成为C++标准库的代名词。（哪年开始的呢。。。）<BR><BR>2000年6月，Krzysztof Czarnecki和Ulrich W．Eisenecker合著的《Generative Programming: <SPAN class=itemSubTitleProduct>Methods, Tools, and Applications</SPAN>》一书中，展示了使用C＋＋模板元编程完成的编译期判断、循环等技巧。（这本书不是以C＋＋为主，C＋＋模板元编程只占一小部分）<BR><BR>2001年2月，Andrei Alexandrescu在出版的《Modern C++ Design》中，对于编译期多态、编译期配置策略等方面做了深入研究，把C＋＋模板技术应用推同更高层次。（不知道是不是他最先研究到这个层次，不过我看到的资料很多是这么说的。）<BR><BR>boost库是由C＋＋标准委员会成员发起的一个C＋＋准标准库，主要是以模板技术构建，很多方面超过了MCD。（不过MCD依旧是我的最爱）<BR><BR>Blitz++和MPL是2个基于C＋＋模板的高效数值计算程序库。<img src ="http://www.cppblog.com/cpunion/aggbug/407.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cpunion/" target="_blank">qiezi</a> 2005-09-23 12:44 <a href="http://www.cppblog.com/cpunion/archive/2005/09/23/407.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>为C＋＋实现一个IDL　（四）</title><link>http://www.cppblog.com/cpunion/archive/2005/09/22/383.html</link><dc:creator>qiezi</dc:creator><author>qiezi</author><pubDate>Thu, 22 Sep 2005 11:13:00 GMT</pubDate><guid>http://www.cppblog.com/cpunion/archive/2005/09/22/383.html</guid><wfw:comment>http://www.cppblog.com/cpunion/comments/383.html</wfw:comment><comments>http://www.cppblog.com/cpunion/archive/2005/09/22/383.html#Feedback</comments><slash:comments>7</slash:comments><wfw:commentRss>http://www.cppblog.com/cpunion/comments/commentRss/383.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/cpunion/services/trackbacks/383.html</trackback:ping><description><![CDATA[如《为C＋＋实现一个IDL（三）》一文中所说，还剩最后一个问题，还是使用前面的测试代码说明。<BR><BR>async_call函数的原型是：<BR><BR>
<DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><SPAN style="COLOR: #000000">typedef&nbsp;</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">(</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000">FUNC_TYPE)(</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">,&nbsp;</SPAN><SPAN style="COLOR: #0000ff">char</SPAN><SPAN style="COLOR: #000000">,&nbsp;</SPAN><SPAN style="COLOR: #0000ff">string</SPAN><SPAN style="COLOR: #000000">,&nbsp;</SPAN><SPAN style="COLOR: #0000ff">short</SPAN><SPAN style="COLOR: #000000">);<BR><BR></SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">&nbsp;async_call&nbsp;(</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&nbsp;v0,&nbsp;</SPAN><SPAN style="COLOR: #0000ff">char</SPAN><SPAN style="COLOR: #000000">&nbsp;v1,&nbsp;</SPAN><SPAN style="COLOR: #0000ff">string</SPAN><SPAN style="COLOR: #000000">&nbsp;v2,&nbsp;FUNC_TYPE&nbsp;func);</SPAN></DIV><BR>这是模板类根据in/out来产生的。<BR><BR>在异步调用中，参数是和操作保存在一起的，因为要交给线程处理。前面已经说过，Method模板类中将保有这些参数，Method的定义如下（以例子中4个参数的特化版本来说明）：<BR><BR>
<DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><SPAN style="COLOR: #000000">template&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000">&nbsp;A,&nbsp;</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000">&nbsp;B,&nbsp;</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000">&nbsp;C,&nbsp;</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000">&nbsp;D</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #0000ff">struct</SPAN><SPAN style="COLOR: #000000">&nbsp;Method&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">(A,B,C,D)</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">&nbsp;:&nbsp;</SPAN><SPAN style="COLOR: #0000ff">public</SPAN><SPAN style="COLOR: #000000">&nbsp;Base&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">&nbsp;typename&nbsp;Loki::TL::MakeTypelist</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">&nbsp;A,B,C,D&nbsp;</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">::Result&nbsp;</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000"><BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;A&nbsp;a;<BR>&nbsp;&nbsp;&nbsp;&nbsp;B&nbsp;b;<BR>&nbsp;&nbsp;&nbsp;&nbsp;C&nbsp;c;<BR>&nbsp;&nbsp;&nbsp;&nbsp;D&nbsp;d;<BR>&nbsp;&nbsp;&nbsp;&nbsp;Method&nbsp;()<BR>&nbsp;&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;parameters.push_back&nbsp;(</SPAN><SPAN style="COLOR: #000000">&amp;</SPAN><SPAN style="COLOR: #000000">a);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;parameters.push_back&nbsp;(</SPAN><SPAN style="COLOR: #000000">&amp;</SPAN><SPAN style="COLOR: #000000">b);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;parameters.push_back&nbsp;(</SPAN><SPAN style="COLOR: #000000">&amp;</SPAN><SPAN style="COLOR: #000000">c);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;parameters.push_back&nbsp;(</SPAN><SPAN style="COLOR: #000000">&amp;</SPAN><SPAN style="COLOR: #000000">d);<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR>};</SPAN></DIV><BR>相应地，Base类使用这个特化版本：<BR><BR>
<DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><SPAN style="COLOR: #000000">template&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000">&nbsp;TYPES,&nbsp;</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000">&nbsp;IN_TYPES</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #0000ff">struct</SPAN><SPAN style="COLOR: #000000">&nbsp;Base&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">TYPES,&nbsp;IN_TYPES,&nbsp;</SPAN><SPAN style="COLOR: #000000">3</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">&nbsp;:&nbsp;</SPAN><SPAN style="COLOR: #0000ff">public</SPAN><SPAN style="COLOR: #000000">&nbsp;IMethod<BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;typename&nbsp;FuncTypeTraits&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">TYPES</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">::Result&nbsp;FUNC_TYPE;<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">&nbsp;async_call&nbsp;(<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typename&nbsp;Loki::TL::TypeAt&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">IN_TYPES,&nbsp;</SPAN><SPAN style="COLOR: #000000">0</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">::Result::OriginalType&nbsp;v0,&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typename&nbsp;Loki::TL::TypeAt&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">IN_TYPES,&nbsp;</SPAN><SPAN style="COLOR: #000000">1</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">::Result::OriginalType&nbsp;v1,&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typename&nbsp;Loki::TL::TypeAt&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">IN_TYPES,&nbsp;</SPAN><SPAN style="COLOR: #000000">2</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">::Result::OriginalType&nbsp;v2,&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FUNC_TYPE&nbsp;func&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">0</SPAN><SPAN style="COLOR: #000000">)<BR>&nbsp;&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR>};</SPAN></DIV><BR>TYPES模板参数中保存了所有的参数类型，IN_TYPES模板参数中保存了所有的in参数类型，但它们不知道如何来对应起来，async_call也不知道如何把几个参数值交给parameters（在IMethod中定义，见上一篇）。<BR><BR>如果我们在生成IN_TYPES的时候，把它在TYPES中的位置（索引）也一起交给它，就能解决这个问题。<BR><BR>InList第二个模板参数是一个常量，当我们把TYPES交给它时，以上面的代码为例，将会使用T_COUNT值为4的偏特化版本。这时候，将会首先推导出IN_TYPES中的第一个类型int，它在IN_TYPES中的索引是0，并接着调用T_COUNT值是3的偏特化版本，这样递归推导，直到调用T_COUNT值为0的偏特化版本，这个过程就结束了。在这个递归过程中，能够得到各个类型以及对应的“索引”值：int: 4, char: 3, string: 2。<BR><BR>注意这个索引值和实际的索引值是有差别的，实际的索引值应该是4-T_COUNT，所以上面的对应关系应该是：int: 0, char: 1, string: 2。<BR><BR>最初传递给InList的TYPES有4个元素，当它递归调用时，这个值就会依次递减，后面的递归调用并不知道应该用4去减掉T_COUNT作为索引，因为4并没有传递过来。简单的解决办法是再加上一个模板参数，让它往下传递，当然这种方式并不好看，好在我们不是真的必须这么做。<BR><BR>注意，在Base类中，它是知道TYPES的个数的，那么只要用这个数减去前面生成的IN_TYPE的“索引”，就能得到这个类型在TYPES中的真正索引。（这部分真是有点罗嗦）<BR><BR>修改InList模板类，让它生成由<FONT style="BACKGROUND-COLOR: #a9a9a9" color=#a9a9a9> </FONT><FONT style="BACKGROUND-COLOR: #a9a9a9">[ in类型以及in类型在TYPES中的“索引”] </FONT>构成的新Typelist。<BR><BR>首先要增加一个辅助模板类：<BR><BR>
<DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><SPAN style="COLOR: #000000">template&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000">&nbsp;T,&nbsp;</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&nbsp;INDEX</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #0000ff">struct</SPAN><SPAN style="COLOR: #000000">&nbsp;TypeReversedIndex<BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;T&nbsp;type;<BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">enum</SPAN><SPAN style="COLOR: #000000">&nbsp;{value&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;INDEX};<BR>};</SPAN></DIV><BR>它能够保存一个类型，以及一个整数。取名为TypeReversedIndex，意思是说它要保存一个Type和一个ReversedIndex（反的索引）。<BR><BR>InList模板类也要修改，OutList依旧是免费赠送：<BR><BR>
<DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><SPAN style="COLOR: #000000">template&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000">&nbsp;T,&nbsp;</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&nbsp;T_COUNT&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;Loki::TL::Length&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">T</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">::value&nbsp;</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #0000ff">struct</SPAN><SPAN style="COLOR: #000000">&nbsp;InList<BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;typename&nbsp;If&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000"><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;InOutTypeTraits&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">typename&nbsp;T::Head</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">::isin,<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typename&nbsp;Loki::Typelist&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">&nbsp;TypeReversedIndex&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">typename&nbsp;T::Head,&nbsp;T_COUNT</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">,&nbsp;typename&nbsp;InList&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">typename&nbsp;T::Tail</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">::Result&nbsp;</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">,&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typename&nbsp;InList&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">typename&nbsp;T::Tail</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">::Result<BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">::Result&nbsp;Result;<BR>};<BR><BR><BR>template&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000">&nbsp;T</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #0000ff">struct</SPAN><SPAN style="COLOR: #000000">&nbsp;InList&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">&nbsp;T,&nbsp;</SPAN><SPAN style="COLOR: #000000">0</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000"><BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;typename&nbsp;Loki::TL::MakeTypelist&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;&gt;</SPAN><SPAN style="COLOR: #000000">::Result&nbsp;Result;<BR>};<BR><BR>template&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000">&nbsp;T,&nbsp;</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&nbsp;T_COUNT&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;Loki::TL::Length&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">T</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">::value&nbsp;</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #0000ff">struct</SPAN><SPAN style="COLOR: #000000">&nbsp;OutList<BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;typename&nbsp;If&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000"><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;InOutTypeTraits&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">typename&nbsp;T::Head</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">::isout,<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typename&nbsp;Loki::Typelist&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">&nbsp;TypeReversedIndex&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">typename&nbsp;T::Head,&nbsp;T_COUNT</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">,&nbsp;typename&nbsp;OutList&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">typename&nbsp;T::Tail</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">::Result&nbsp;</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">,&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typename&nbsp;OutList&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">typename&nbsp;T::Tail</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">::Result<BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">::Result&nbsp;Result;<BR>};<BR><BR><BR>template&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000">&nbsp;T</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #0000ff">struct</SPAN><SPAN style="COLOR: #000000">&nbsp;OutList&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">&nbsp;T,&nbsp;</SPAN><SPAN style="COLOR: #000000">0</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000"><BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;typename&nbsp;Loki::TL::MakeTypelist&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;&gt;</SPAN><SPAN style="COLOR: #000000">::Result&nbsp;Result;<BR>};</SPAN></DIV><BR>Base类就可以写出来了：<BR><BR>
<DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><SPAN style="COLOR: #000000">template&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000">&nbsp;TYPES,&nbsp;</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000">&nbsp;IN_TYPES</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #0000ff">struct</SPAN><SPAN style="COLOR: #000000">&nbsp;Base&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">TYPES,&nbsp;IN_TYPES,&nbsp;</SPAN><SPAN style="COLOR: #000000">3</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">&nbsp;:&nbsp;</SPAN><SPAN style="COLOR: #0000ff">public</SPAN><SPAN style="COLOR: #000000">&nbsp;IMethod<BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;typename&nbsp;FuncTypeTraits&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">TYPES</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">::Result&nbsp;FUNC_TYPE;<BR>&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;IN_TYPES&nbsp;type;<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">enum</SPAN><SPAN style="COLOR: #000000">&nbsp;{TYPES_COUNT&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;typename&nbsp;Loki::TL::Length</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">TYPES</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">::value};<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">&nbsp;async_call&nbsp;(<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typename&nbsp;Loki::TL::TypeAt&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">IN_TYPES,&nbsp;</SPAN><SPAN style="COLOR: #000000">0</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">::Result::type::OriginalType&nbsp;v0,&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typename&nbsp;Loki::TL::TypeAt&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">IN_TYPES,&nbsp;</SPAN><SPAN style="COLOR: #000000">1</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">::Result::type::OriginalType&nbsp;v1,&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typename&nbsp;Loki::TL::TypeAt&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">IN_TYPES,&nbsp;</SPAN><SPAN style="COLOR: #000000">2</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">::Result::type::OriginalType&nbsp;v2,&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FUNC_TYPE&nbsp;func&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">0</SPAN><SPAN style="COLOR: #000000">)<BR>&nbsp;&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;((typename&nbsp;Loki::TL::TypeAt&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">IN_TYPES,&nbsp;</SPAN><SPAN style="COLOR: #000000">0</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">::Result::type</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000">)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;parameters[TYPES_COUNT&nbsp;</SPAN><SPAN style="COLOR: #000000">-</SPAN><SPAN style="COLOR: #000000">&nbsp;typename&nbsp;Loki::TL::TypeAt&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">IN_TYPES,&nbsp;</SPAN><SPAN style="COLOR: #000000">0</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">::Result::value])</SPAN><SPAN style="COLOR: #000000">-&gt;</SPAN><SPAN style="COLOR: #000000">setValue&nbsp;(v0);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;((typename&nbsp;Loki::TL::TypeAt&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">IN_TYPES,&nbsp;</SPAN><SPAN style="COLOR: #000000">1</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">::Result::type</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000">)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;parameters[TYPES_COUNT&nbsp;</SPAN><SPAN style="COLOR: #000000">-</SPAN><SPAN style="COLOR: #000000">&nbsp;typename&nbsp;Loki::TL::TypeAt&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">IN_TYPES,&nbsp;</SPAN><SPAN style="COLOR: #000000">1</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">::Result::value])</SPAN><SPAN style="COLOR: #000000">-&gt;</SPAN><SPAN style="COLOR: #000000">setValue&nbsp;(v1);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;((typename&nbsp;Loki::TL::TypeAt&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">IN_TYPES,&nbsp;</SPAN><SPAN style="COLOR: #000000">2</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">::Result::type</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000">)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;parameters[TYPES_COUNT&nbsp;</SPAN><SPAN style="COLOR: #000000">-</SPAN><SPAN style="COLOR: #000000">&nbsp;typename&nbsp;Loki::TL::TypeAt&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">IN_TYPES,&nbsp;</SPAN><SPAN style="COLOR: #000000">2</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">::Result::value])</SPAN><SPAN style="COLOR: #000000">-&gt;</SPAN><SPAN style="COLOR: #000000">setValue&nbsp;(v2);<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR>};</SPAN></DIV><BR>parameters中存放的是IParameter*类型，这里使用了强制转型，并调用in/inout模板类的setValue方法给它赋值。<BR><BR>为了测试结果，我为IParameter加上了void print () const虚函数，并在in/inout/out模板类中实现它，打印出类型，in/inout类中还将打印出参数值。<BR><BR>
<DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000">&nbsp;IParameter<BR>{<BR></SPAN><SPAN style="COLOR: #0000ff">public</SPAN><SPAN style="COLOR: #000000">:<BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">virtual</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">&nbsp;print&nbsp;()&nbsp;</SPAN><SPAN style="COLOR: #0000ff">const</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">0</SPAN><SPAN style="COLOR: #000000">;<BR>};</SPAN></DIV><BR>
<DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><SPAN style="COLOR: #000000">template&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000">&nbsp;T</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #0000ff">struct</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">in</SPAN><SPAN style="COLOR: #000000">&nbsp;:&nbsp;</SPAN><SPAN style="COLOR: #0000ff">public</SPAN><SPAN style="COLOR: #000000">&nbsp;IParameter<BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;T&nbsp;OriginalType;<BR>&nbsp;&nbsp;&nbsp;&nbsp;T&nbsp;value;<BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">&nbsp;setValue&nbsp;(T&nbsp;v){<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;v;<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">&nbsp;print&nbsp;()&nbsp;</SPAN><SPAN style="COLOR: #0000ff">const</SPAN><SPAN style="COLOR: #000000">&nbsp;{&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cout&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;&lt;</SPAN><SPAN style="COLOR: #000000">&nbsp;typeid(</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #0000ff">this</SPAN><SPAN style="COLOR: #000000">).name()&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;&lt;</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">:&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;&lt;</SPAN><SPAN style="COLOR: #000000">&nbsp;value&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;&lt;</SPAN><SPAN style="COLOR: #000000">&nbsp;endl;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR>};<BR><BR>template&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000">&nbsp;T</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #0000ff">struct</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">out</SPAN><SPAN style="COLOR: #000000">&nbsp;:&nbsp;</SPAN><SPAN style="COLOR: #0000ff">public</SPAN><SPAN style="COLOR: #000000">&nbsp;IParameter<BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;T&nbsp;OriginalType;<BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">virtual</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">&nbsp;print&nbsp;()&nbsp;</SPAN><SPAN style="COLOR: #0000ff">const</SPAN><SPAN style="COLOR: #000000">&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cout&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;&lt;</SPAN><SPAN style="COLOR: #000000">&nbsp;typeid(</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #0000ff">this</SPAN><SPAN style="COLOR: #000000">).name()&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;&lt;</SPAN><SPAN style="COLOR: #000000">&nbsp;endl;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR>};<BR><BR>template&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000">&nbsp;T</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #0000ff">struct</SPAN><SPAN style="COLOR: #000000">&nbsp;inout&nbsp;:&nbsp;</SPAN><SPAN style="COLOR: #0000ff">public</SPAN><SPAN style="COLOR: #000000">&nbsp;IParameter<BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;T&nbsp;OriginalType;<BR>&nbsp;&nbsp;&nbsp;&nbsp;T&nbsp;value;<BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">&nbsp;setValue&nbsp;(T&nbsp;v){<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;v;<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">virtual</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">&nbsp;print&nbsp;()&nbsp;</SPAN><SPAN style="COLOR: #0000ff">const</SPAN><SPAN style="COLOR: #000000">&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cout&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;&lt;</SPAN><SPAN style="COLOR: #000000">&nbsp;typeid(</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #0000ff">this</SPAN><SPAN style="COLOR: #000000">).name()&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;&lt;</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">:&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;&lt;</SPAN><SPAN style="COLOR: #000000">&nbsp;value&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;&lt;</SPAN><SPAN style="COLOR: #000000">&nbsp;endl;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR>};</SPAN></DIV><BR>并在Base::async_call中调用parameters中所有对象的print函数来输出一些调试信息：<BR><BR>
<DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><SPAN style="COLOR: #0000ff">for</SPAN><SPAN style="COLOR: #000000">&nbsp;(size_t&nbsp;i&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">0</SPAN><SPAN style="COLOR: #000000">;&nbsp;i&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">&nbsp;parameters.size();&nbsp;i&nbsp;</SPAN><SPAN style="COLOR: #000000">++</SPAN><SPAN style="COLOR: #000000">)<BR>&nbsp;&nbsp;&nbsp;&nbsp;parameters[i]</SPAN><SPAN style="COLOR: #000000">-&gt;</SPAN><SPAN style="COLOR: #000000">print&nbsp;();</SPAN></DIV><BR>简单测试了2种类型，不能保证所有代码都是正确的，毕竟是手工写出来的也没经过检查，模板类在没有实例化的时候某些错误是不会报告的。<BR><BR>测试代码如下：<BR><BR>
<DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">&nbsp;test_func&nbsp;(</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&nbsp;v0,&nbsp;</SPAN><SPAN style="COLOR: #0000ff">char</SPAN><SPAN style="COLOR: #000000">&nbsp;v1,&nbsp;</SPAN><SPAN style="COLOR: #0000ff">string</SPAN><SPAN style="COLOR: #000000">&nbsp;v2,&nbsp;</SPAN><SPAN style="COLOR: #0000ff">short</SPAN><SPAN style="COLOR: #000000">&nbsp;v3)<BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;cout&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;&lt;</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">===========================================</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;&lt;</SPAN><SPAN style="COLOR: #000000">&nbsp;endl;<BR>&nbsp;&nbsp;&nbsp;&nbsp;cout&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;&lt;</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">test_func(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;&lt;</SPAN><SPAN style="COLOR: #000000">&nbsp;v0&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;&lt;</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">,&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;&lt;</SPAN><SPAN style="COLOR: #000000">&nbsp;v1&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;&lt;</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">,&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;&lt;</SPAN><SPAN style="COLOR: #000000">&nbsp;v2&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;&lt;</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">,&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;&lt;</SPAN><SPAN style="COLOR: #000000">&nbsp;v3&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;&lt;</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">)</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;&lt;</SPAN><SPAN style="COLOR: #000000">&nbsp;endl;<BR>}<BR><BR></SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">&nbsp;test_func1&nbsp;(</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&nbsp;v0,&nbsp;</SPAN><SPAN style="COLOR: #0000ff">char</SPAN><SPAN style="COLOR: #000000">&nbsp;v1,&nbsp;</SPAN><SPAN style="COLOR: #0000ff">short</SPAN><SPAN style="COLOR: #000000">&nbsp;v2,&nbsp;</SPAN><SPAN style="COLOR: #0000ff">string</SPAN><SPAN style="COLOR: #000000">&nbsp;v3)<BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;cout&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;&lt;</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">===========================================</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;&lt;</SPAN><SPAN style="COLOR: #000000">&nbsp;endl;<BR>&nbsp;&nbsp;&nbsp;&nbsp;cout&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;&lt;</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">test_func1(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;&lt;</SPAN><SPAN style="COLOR: #000000">&nbsp;v0&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;&lt;</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">,&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;&lt;</SPAN><SPAN style="COLOR: #000000">&nbsp;v1&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;&lt;</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">,&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;&lt;</SPAN><SPAN style="COLOR: #000000">&nbsp;v2&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;&lt;</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">,&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;&lt;</SPAN><SPAN style="COLOR: #000000">&nbsp;v3&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;&lt;</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">)</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;&lt;</SPAN><SPAN style="COLOR: #000000">&nbsp;endl;<BR>}<BR><BR></SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&nbsp;main()<BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Method&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">(</SPAN><SPAN style="COLOR: #0000ff">in</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">,&nbsp;</SPAN><SPAN style="COLOR: #0000ff">in</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #0000ff">char</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">,&nbsp;inout</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #0000ff">string</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">,&nbsp;</SPAN><SPAN style="COLOR: #0000ff">out</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #0000ff">short</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">)&nbsp;</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">&nbsp;m;<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;m.async_call(</SPAN><SPAN style="COLOR: #000000">3</SPAN><SPAN style="COLOR: #000000">,&nbsp;</SPAN><SPAN style="COLOR: #000000">'</SPAN><SPAN style="COLOR: #000000">a</SPAN><SPAN style="COLOR: #000000">'</SPAN><SPAN style="COLOR: #000000">,&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">test</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cout&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;&lt;</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">===========================================</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;&lt;</SPAN><SPAN style="COLOR: #000000">&nbsp;endl;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;m.async_call(</SPAN><SPAN style="COLOR: #000000">3</SPAN><SPAN style="COLOR: #000000">,&nbsp;</SPAN><SPAN style="COLOR: #000000">'</SPAN><SPAN style="COLOR: #000000">a</SPAN><SPAN style="COLOR: #000000">'</SPAN><SPAN style="COLOR: #000000">,&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">test</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">,&nbsp;test_func);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cout&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;&lt;</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">===========================================</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;&lt;</SPAN><SPAN style="COLOR: #000000">&nbsp;endl;<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Method&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #0000ff">string</SPAN><SPAN style="COLOR: #000000">(</SPAN><SPAN style="COLOR: #0000ff">in</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">,&nbsp;</SPAN><SPAN style="COLOR: #0000ff">out</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #0000ff">char</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">,&nbsp;inout</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #0000ff">short</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">)</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">&nbsp;m;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;m.async_call(</SPAN><SPAN style="COLOR: #000000">3</SPAN><SPAN style="COLOR: #000000">,&nbsp;</SPAN><SPAN style="COLOR: #000000">4</SPAN><SPAN style="COLOR: #000000">);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cout&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;&lt;</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">===========================================</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;&lt;</SPAN><SPAN style="COLOR: #000000">&nbsp;endl;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;m.async_call(</SPAN><SPAN style="COLOR: #000000">3</SPAN><SPAN style="COLOR: #000000">,&nbsp;</SPAN><SPAN style="COLOR: #000000">4</SPAN><SPAN style="COLOR: #000000">,&nbsp;test_func1);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cout&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;&lt;</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">===========================================</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;&lt;</SPAN><SPAN style="COLOR: #000000">&nbsp;endl;<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">return</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">0</SPAN><SPAN style="COLOR: #000000">;<BR>}</SPAN></DIV><BR>全部代码太长，就不一一罗列于此了，可以点击<STRONG><A href="http://www.cnblogs.com/Files/cpunion/asgard_test.zip">这里</A></STRONG>下载。<BR><img src ="http://www.cppblog.com/cpunion/aggbug/383.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cpunion/" target="_blank">qiezi</a> 2005-09-22 19:13 <a href="http://www.cppblog.com/cpunion/archive/2005/09/22/383.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>为C＋＋实现一个IDL　（三）</title><link>http://www.cppblog.com/cpunion/archive/2005/09/21/366.html</link><dc:creator>qiezi</dc:creator><author>qiezi</author><pubDate>Wed, 21 Sep 2005 12:34:00 GMT</pubDate><guid>http://www.cppblog.com/cpunion/archive/2005/09/21/366.html</guid><wfw:comment>http://www.cppblog.com/cpunion/comments/366.html</wfw:comment><comments>http://www.cppblog.com/cpunion/archive/2005/09/21/366.html#Feedback</comments><slash:comments>6</slash:comments><wfw:commentRss>http://www.cppblog.com/cpunion/comments/commentRss/366.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/cpunion/services/trackbacks/366.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 一、修正错误。首先修正第二篇中的一些错误，错误的内容可见第二篇的评论。在Base类中，FUNC_TYPE需要所有的in/out类型，如果Method的模板参数——即函数类型参数——的返回值不是void，则把它装配成out参数，作为FUNC_TYPE函数类型的最后一个参数，这可以通过偏特化来实现。修改Method模板类，把所有类型包装成一个Typelist，直接传递给Base模板类，由Base去推导...&nbsp;&nbsp;<a href='http://www.cppblog.com/cpunion/archive/2005/09/21/366.html'>阅读全文</a><img src ="http://www.cppblog.com/cpunion/aggbug/366.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cpunion/" target="_blank">qiezi</a> 2005-09-21 20:34 <a href="http://www.cppblog.com/cpunion/archive/2005/09/21/366.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>为C＋＋实现一个IDL　（二）</title><link>http://www.cppblog.com/cpunion/archive/2005/09/20/349.html</link><dc:creator>qiezi</dc:creator><author>qiezi</author><pubDate>Tue, 20 Sep 2005 14:34:00 GMT</pubDate><guid>http://www.cppblog.com/cpunion/archive/2005/09/20/349.html</guid><wfw:comment>http://www.cppblog.com/cpunion/comments/349.html</wfw:comment><comments>http://www.cppblog.com/cpunion/archive/2005/09/20/349.html#Feedback</comments><slash:comments>6</slash:comments><wfw:commentRss>http://www.cppblog.com/cpunion/comments/commentRss/349.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/cpunion/services/trackbacks/349.html</trackback:ping><description><![CDATA[<P>说明：<BR>要看懂后面那部分代码，即使用Typelist的部分，最好预先看过《C＋＋设计新思维》，英文版名为《Modern C++ Design》。<BR>If模板类在写完后想起来好像在哪见过，早晨去公司查阅了一下，在《产生式编程——方法、工具与应用》一书中有讲，英文名为《Generative Programming -- Methods, Tools, and Applications》基本和本篇中一个样。<BR><BR><BR>前2篇乱七八糟地讲了一些，有一个遗留问题，函数原型的推导。<BR><BR>简要描述如下：</P>
<DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><SPAN style="COLOR: #000000">Method&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">(</SPAN><SPAN style="COLOR: #0000ff">in</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">,&nbsp;</SPAN><SPAN style="COLOR: #0000ff">in</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #0000ff">char</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">,&nbsp;inout</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #0000ff">string</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">,&nbsp;</SPAN><SPAN style="COLOR: #0000ff">out</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #0000ff">short</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">)&nbsp;</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">&nbsp;method;<BR><BR></SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000">&nbsp;同步调用</SPAN><SPAN style="COLOR: #008000"><BR></SPAN><SPAN style="COLOR: #0000ff">string</SPAN><SPAN style="COLOR: #000000">&nbsp;str&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">hello</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">;<BR></SPAN><SPAN style="COLOR: #0000ff">short</SPAN><SPAN style="COLOR: #000000">&nbsp;value&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">2</SPAN><SPAN style="COLOR: #000000">;<BR>method&nbsp;(</SPAN><SPAN style="COLOR: #000000">3</SPAN><SPAN style="COLOR: #000000">,&nbsp;</SPAN><SPAN style="COLOR: #000000">'</SPAN><SPAN style="COLOR: #000000">a</SPAN><SPAN style="COLOR: #000000">'</SPAN><SPAN style="COLOR: #000000">,&nbsp;str,&nbsp;value</SPAN><SPAN style="COLOR: #000000">);<BR><BR></SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000">&nbsp;异步调用1</SPAN><SPAN style="COLOR: #008000"><BR></SPAN><SPAN style="COLOR: #000000">method.async_call&nbsp;(</SPAN><SPAN style="COLOR: #000000">3</SPAN><SPAN style="COLOR: #000000">,&nbsp;</SPAN><SPAN style="COLOR: #000000">'</SPAN><SPAN style="COLOR: #000000">a</SPAN><SPAN style="COLOR: #000000">'</SPAN><SPAN style="COLOR: #000000">,&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">hello</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">);<BR><BR></SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000">&nbsp;异步调用2</SPAN><SPAN style="COLOR: #008000"><BR></SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">&nbsp;test_func&nbsp;(</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">,&nbsp;</SPAN><SPAN style="COLOR: #0000ff">char</SPAN><SPAN style="COLOR: #000000">,&nbsp;</SPAN><SPAN style="COLOR: #0000ff">string</SPAN><SPAN style="COLOR: #000000">,&nbsp;</SPAN><SPAN style="COLOR: #0000ff">short</SPAN><SPAN style="COLOR: #000000">);<BR>method.async_call&nbsp;(</SPAN><SPAN style="COLOR: #000000">3</SPAN><SPAN style="COLOR: #000000">,&nbsp;</SPAN><SPAN style="COLOR: #000000">'</SPAN><SPAN style="COLOR: #000000">a</SPAN><SPAN style="COLOR: #000000">'</SPAN><SPAN style="COLOR: #000000">,&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">hello</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">,&nbsp;test_func);</SPAN></DIV>
<P><BR>要产生这3种函数形式。参数类型如何转换，是以后的话题，本篇主要解决异步调用的函数原形推导问题。本篇也不讨论Method的模板参数（即那个函数类型）返回类型不为void的情况。<BR><BR>第一种形式，同步调用，比较好处理，参数个数和模板参数的数量相同。<BR><BR>后2种形式，如何让编译器根据in/out来推导出函数原型？<BR><BR>我们需要编译器做这样的处理，async_call的参数类型中，in类型的参数将保留，out类型的参数不需要，inout类型也需要保留。<BR><BR>要用到的Loki头文件：</P>
<DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><SPAN style="COLOR: #000000">#include&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">static_check.h</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000"><BR>#include&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">Typelist.h</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000"><BR><BR></SPAN><SPAN style="COLOR: #0000ff">using</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">namespace</SPAN><SPAN style="COLOR: #000000">&nbsp;Loki;<BR></SPAN><SPAN style="COLOR: #0000ff">using</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">namespace</SPAN><SPAN style="COLOR: #000000">&nbsp;Loki::TL;</SPAN></DIV>
<P><BR>首先看看in/inout/out的声明。为了简化，这里去掉了跟类型推导无关的部分。</P>
<DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000">&nbsp;NullType<BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;NullType&nbsp;();<BR>};<BR><BR>template&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000">&nbsp;T</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #0000ff">struct</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">in</SPAN><SPAN style="COLOR: #000000"><BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;T&nbsp;OriginalType;<BR>};<BR><BR>template&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000">&nbsp;T</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #0000ff">struct</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">out</SPAN><SPAN style="COLOR: #000000"><BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;T&nbsp;OriginalType;<BR>};<BR><BR>template&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000">&nbsp;T</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #0000ff">struct</SPAN><SPAN style="COLOR: #000000">&nbsp;inout<BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;T&nbsp;OriginalType;<BR>};<BR></SPAN></DIV><BR>下面Method模板类的声明，使用偏特化来产生代码。为了简化，我只取函数参数个数为4个参数的版本，比照着上面的代码来解释，只解释method.async_call (3, 'a', "hello", test_func);这个版本，因为另一个比它简单。<BR><BR>
<DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><SPAN style="COLOR: #000000">template&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000">&nbsp;T</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #0000ff">struct</SPAN><SPAN style="COLOR: #000000">&nbsp;Method<BR>{<BR>};<BR><BR>template&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000">&nbsp;Ret,&nbsp;</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000">&nbsp;A,&nbsp;</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000">&nbsp;B,&nbsp;</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000">&nbsp;C,&nbsp;</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000">&nbsp;D</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #0000ff">struct</SPAN><SPAN style="COLOR: #000000">&nbsp;Method&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">Ret(A,B,C,D)</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">&nbsp;<BR>{<BR>};</SPAN></DIV>
<P><BR>根据上面Method的定义，Method &lt; void(in<INT>, in<CHAR>, inout<STRING>, out<SHORT>) &gt; ，async_call函数的类型将是：<SPAN style="COLOR: #000000"></P>
<DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><SPAN style="COLOR: #000000">typedef&nbsp;</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">&nbsp;(</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000">FUNC_TYPE)(</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">,&nbsp;</SPAN><SPAN style="COLOR: #0000ff">char</SPAN><SPAN style="COLOR: #000000">,&nbsp;</SPAN><SPAN style="COLOR: #0000ff">string</SPAN><SPAN style="COLOR: #000000">,&nbsp;</SPAN><SPAN style="COLOR: #0000ff">short</SPAN><SPAN style="COLOR: #000000">);<BR></SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">&nbsp;async_call&nbsp;(</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">,&nbsp;</SPAN><SPAN style="COLOR: #0000ff">char</SPAN><SPAN style="COLOR: #000000">,&nbsp;</SPAN><SPAN style="COLOR: #0000ff">string</SPAN><SPAN style="COLOR: #000000">,&nbsp;FUNC_TYPE&nbsp;func);</SPAN></DIV></SPAN><BR>实际上FUNC_TYPE应该能够接受更广泛的类型，比如void(int, char, char*, short)，这可以在内部做一些转换，不过本篇的重点不在这里，所以只讲上面的那种形式。<BR><BR>直接在Method类中实现有些麻烦，所以我把这个函数放在一个基类中实现，只要编译器能帮我们推导出下面这种形式就行了：<BR><BR>
<DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><SPAN style="COLOR: #000000">template&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000">&nbsp;Ret,&nbsp;</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000">&nbsp;A,&nbsp;</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000">&nbsp;B,&nbsp;</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000">&nbsp;C,&nbsp;</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000">&nbsp;D</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #0000ff">struct</SPAN><SPAN style="COLOR: #000000">&nbsp;Method&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">Ret(A,B,C,D)</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">&nbsp;:&nbsp;</SPAN><SPAN style="COLOR: #0000ff">public</SPAN><SPAN style="COLOR: #000000">&nbsp;Base&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">&nbsp;A,&nbsp;B,&nbsp;C&nbsp;</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000"><BR>{<BR>};</SPAN></DIV>
<P><BR>注意，这里是以Method &lt; void(in<INT>, in<CHAR>, inout<STRING>, out<SHORT>) &gt;这种形式来讲的，才会有上面那种继承关系。而实际上，由于in/out在参数中的位置、数量都是未知的，要到定义时才能确定，所以使用模板来推导。（入正题了）</P>
<P>也就是说，只要我们能使用静态推导方式，获得A,B,C,D这四个参数中所有的in类型，把它交给Base作为模板参数就成了。</P>
<P>这里需要一个辅助的模板类，用来在编译时帮助推导：<BR><BR></P>
<DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><SPAN style="COLOR: #000000">template&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000">&nbsp;T</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000">&nbsp;InOutTypeTraits<BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;Loki::CompileTimeError&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #0000ff">false</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">&nbsp;Not_Supported_Type;<BR>};<BR><BR>template&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000">&nbsp;T</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #0000ff">struct</SPAN><SPAN style="COLOR: #000000">&nbsp;InOutTypeTraits&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">in</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">T</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000"><BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">enum</SPAN><SPAN style="COLOR: #000000">&nbsp;{isin</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">1</SPAN><SPAN style="COLOR: #000000">,&nbsp;isout</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">0</SPAN><SPAN style="COLOR: #000000">};<BR>};<BR><BR>template&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000">&nbsp;T</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #0000ff">struct</SPAN><SPAN style="COLOR: #000000">&nbsp;InOutTypeTraits&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">out</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">T</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000"><BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">enum</SPAN><SPAN style="COLOR: #000000">&nbsp;{isin</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">0</SPAN><SPAN style="COLOR: #000000">,&nbsp;isout</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">1</SPAN><SPAN style="COLOR: #000000">};<BR>};<BR><BR>template&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000">&nbsp;T</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #0000ff">struct</SPAN><SPAN style="COLOR: #000000">&nbsp;InOutTypeTraits&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">&nbsp;inout</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">T</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000"><BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">enum</SPAN><SPAN style="COLOR: #000000">&nbsp;{isin</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">1</SPAN><SPAN style="COLOR: #000000">,&nbsp;isout</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">1</SPAN><SPAN style="COLOR: #000000">};<BR>};<BR><BR>template&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;&gt;</SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #0000ff">struct</SPAN><SPAN style="COLOR: #000000">&nbsp;InOutTypeTraits&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">&nbsp;NullType&nbsp;</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000"><BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">enum</SPAN><SPAN style="COLOR: #000000">&nbsp;{isin</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">0</SPAN><SPAN style="COLOR: #000000">,&nbsp;isout</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">0</SPAN><SPAN style="COLOR: #000000">};<BR>};</SPAN></DIV></SPAN><BR>通过另一个模板类InList来帮我们产生所有的in类型，它的结果是一个Typelist。为了方便以后使用，我把out类型产生器也做了一个OutList。<BR><BR>
<DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><SPAN style="COLOR: #000000">template&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&nbsp;CONDITION,&nbsp;</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000">&nbsp;_IF,&nbsp;</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000">&nbsp;_ELSE</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #0000ff">struct</SPAN><SPAN style="COLOR: #000000">&nbsp;If<BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;_IF&nbsp;Result;<BR>};<BR><BR>template&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000">&nbsp;_IF,&nbsp;</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000">&nbsp;_ELSE</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #0000ff">struct</SPAN><SPAN style="COLOR: #000000">&nbsp;If&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">0</SPAN><SPAN style="COLOR: #000000">,&nbsp;_IF,&nbsp;_ELSE</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000"><BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;_ELSE&nbsp;Result;<BR>};<BR><BR>template&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000">&nbsp;A&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;NullType,&nbsp;</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000">&nbsp;B&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;NullType,&nbsp;</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000">&nbsp;C&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;NullType,&nbsp;</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000">&nbsp;D&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;NullType,&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000">&nbsp;E&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;NullType,&nbsp;</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000">&nbsp;F&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;NullType,&nbsp;</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000">&nbsp;G&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;NullType,&nbsp;</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000">&nbsp;H&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;NullType<BR></SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #0000ff">struct</SPAN><SPAN style="COLOR: #000000">&nbsp;InList<BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;typename&nbsp;If&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;InOutTypeTraits&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">A</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">::isin,<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typename&nbsp;Typelist&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">&nbsp;A,&nbsp;typename&nbsp;InList</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">B,C,D,E,F,G</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">::Result&nbsp;</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">,&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typename&nbsp;InList</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">B,C,D,E,F,G,H</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">::Result&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">::Result&nbsp;Result;<BR>};<BR><BR>template&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000">&nbsp;A</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #0000ff">struct</SPAN><SPAN style="COLOR: #000000">&nbsp;InList&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">A,&nbsp;NullType,&nbsp;NullType,&nbsp;NullType,&nbsp;NullType,&nbsp;NullType,&nbsp;NullType,&nbsp;NullType</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000"><BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;typename&nbsp;If&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000"><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;InOutTypeTraits&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">A</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">::isin,<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typename&nbsp;MakeTypelist&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">A</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">::Result,<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typename&nbsp;MakeTypelist&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;&gt;</SPAN><SPAN style="COLOR: #000000">::Result<BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">::Result&nbsp;Result;<BR>};<BR><BR>template&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000">&nbsp;A&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;NullType,&nbsp;</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000">&nbsp;B&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;NullType,&nbsp;</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000">&nbsp;C&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;NullType,&nbsp;</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000">&nbsp;D&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;NullType,&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000">&nbsp;E&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;NullType,&nbsp;</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000">&nbsp;F&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;NullType,&nbsp;</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000">&nbsp;G&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;NullType,&nbsp;</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000">&nbsp;H&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;NullType<BR></SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #0000ff">struct</SPAN><SPAN style="COLOR: #000000">&nbsp;OutList<BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;typename&nbsp;If&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;InOutTypeTraits</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">A</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">::isout,<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typename&nbsp;Typelist&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">&nbsp;A,&nbsp;typename&nbsp;OutList</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">B,C,D,E,F,G</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">::Result&nbsp;</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">,&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typename&nbsp;OutList</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">B,C,D,E,F,G,H</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">::Result&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">::Result&nbsp;Result;<BR>};<BR><BR>template&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000">&nbsp;A</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #0000ff">struct</SPAN><SPAN style="COLOR: #000000">&nbsp;OutList&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">A,&nbsp;NullType,&nbsp;NullType,&nbsp;NullType,&nbsp;NullType,&nbsp;NullType,&nbsp;NullType,&nbsp;NullType</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000"><BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;typename&nbsp;MakeTypelist&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">A</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">::Result&nbsp;Result;<BR>};</SPAN></DIV><BR>它的原理是，根据If模板类来判断一个类型是不是in类型，是的话就把它加入到Typelist中，不是就排除它。<BR><BR>InList <IN<INT>, in<CHAR>, inout<STRING>, out<SHORT>::Result是一个Typelist <IN<INT>, Typelist<IN<CHAR>, Typelist<INOUT<STRING>, NullType&gt; &gt; &gt;类型，说简单点，它和MakeTypelist &lt; in<INT>, in<CHAR>, inout<STIRNG> &gt;::Result是等价的。<BR><BR>现在Base模板类将接受一个模板参数，它是一个Typelist类型，这个不详细讲了，把它的定义写出来：<BR><BR>
<DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><SPAN style="COLOR: #000000">template&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000">&nbsp;T,&nbsp;</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&nbsp;T_COUNT&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;Length&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">IN_TYPE</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">::value&nbsp;</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #0000ff">struct</SPAN><SPAN style="COLOR: #000000">&nbsp;Base<BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;Loki::CompileTimeError&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #0000ff">false</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">&nbsp;Only_Use_Partial_Specialisation_Version;<BR>};<BR><BR>template&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000">&nbsp;T</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #0000ff">struct</SPAN><SPAN style="COLOR: #000000">&nbsp;Base&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">T,&nbsp;</SPAN><SPAN style="COLOR: #000000">0</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000"><BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">(</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000">FUNC_TYPE)();<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;template&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000">&nbsp;FUNC_TYPE</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000"><BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">&nbsp;async_call&nbsp;(FUNC_TYPE&nbsp;func)<BR>&nbsp;&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">&nbsp;async_call&nbsp;()<BR>&nbsp;&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR>};<BR><BR>template&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000">&nbsp;T</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #0000ff">struct</SPAN><SPAN style="COLOR: #000000">&nbsp;Base&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">T,&nbsp;</SPAN><SPAN style="COLOR: #000000">1</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000"><BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">(</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000">FUNC_TYPE)(<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typename&nbsp;TypeAt&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">T,&nbsp;</SPAN><SPAN style="COLOR: #000000">0</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">::Result::OriginalType);<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">&nbsp;async_call&nbsp;(<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typename&nbsp;TypeAt&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">T,&nbsp;</SPAN><SPAN style="COLOR: #000000">0</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">::Result::OriginalType&nbsp;v0,<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FUNC_TYPE&nbsp;func)<BR>&nbsp;&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">&nbsp;async_call&nbsp;(typename&nbsp;TypeAt&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">T,&nbsp;</SPAN><SPAN style="COLOR: #000000">0</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">::Result::OriginalType&nbsp;v0)<BR>&nbsp;&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR>};<BR><BR>template&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000">&nbsp;T</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #0000ff">struct</SPAN><SPAN style="COLOR: #000000">&nbsp;Base&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">T,&nbsp;</SPAN><SPAN style="COLOR: #000000">2</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000"><BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">(</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000">FUNC_TYPE)(<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typename&nbsp;TypeAt&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">T,&nbsp;</SPAN><SPAN style="COLOR: #000000">0</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">::Result::OriginalType,<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typename&nbsp;TypeAt&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">T,&nbsp;</SPAN><SPAN style="COLOR: #000000">1</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">::Result::OriginalType);<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">&nbsp;async_call&nbsp;(<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typename&nbsp;TypeAt&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">T,&nbsp;</SPAN><SPAN style="COLOR: #000000">0</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">::Result::OriginalType&nbsp;v0,&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typename&nbsp;TypeAt&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">T,&nbsp;</SPAN><SPAN style="COLOR: #000000">1</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">::Result::OriginalType&nbsp;v1,&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FUNC_TYPE&nbsp;func)<BR>&nbsp;&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">&nbsp;async_call&nbsp;(<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typename&nbsp;TypeAt&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">T,&nbsp;</SPAN><SPAN style="COLOR: #000000">0</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">::Result::OriginalType&nbsp;v0,&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typename&nbsp;TypeAt&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">T,&nbsp;</SPAN><SPAN style="COLOR: #000000">1</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">::Result::OriginalType&nbsp;v1)<BR>&nbsp;&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR>};<BR><BR>template&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000">&nbsp;T</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #0000ff">struct</SPAN><SPAN style="COLOR: #000000">&nbsp;Base&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">T,&nbsp;</SPAN><SPAN style="COLOR: #000000">3</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000"><BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">(</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000">FUNC_TYPE)(<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typename&nbsp;TypeAt&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">T,&nbsp;</SPAN><SPAN style="COLOR: #000000">0</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">::Result::OriginalType,&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typename&nbsp;TypeAt&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">T,&nbsp;</SPAN><SPAN style="COLOR: #000000">1</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">::Result::OriginalType,<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typename&nbsp;TypeAt&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">T,&nbsp;</SPAN><SPAN style="COLOR: #000000">2</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">::Result::OriginalType);<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">&nbsp;async_call&nbsp;(<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typename&nbsp;TypeAt&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">T,&nbsp;</SPAN><SPAN style="COLOR: #000000">0</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">::Result::OriginalType&nbsp;v0,&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typename&nbsp;TypeAt&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">T,&nbsp;</SPAN><SPAN style="COLOR: #000000">1</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">::Result::OriginalType&nbsp;v1,&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typename&nbsp;TypeAt&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">T,&nbsp;</SPAN><SPAN style="COLOR: #000000">2</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">::Result::OriginalType&nbsp;v2,&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FUNC_TYPE&nbsp;func)<BR>&nbsp;&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">&nbsp;async_call&nbsp;(<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typename&nbsp;TypeAt&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">T,&nbsp;</SPAN><SPAN style="COLOR: #000000">0</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">::Result::OriginalType&nbsp;v0,<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typename&nbsp;TypeAt&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">T,&nbsp;</SPAN><SPAN style="COLOR: #000000">1</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">::Result::OriginalType&nbsp;v1,<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typename&nbsp;TypeAt&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">T,&nbsp;</SPAN><SPAN style="COLOR: #000000">2</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">::Result::OriginalType&nbsp;v2)<BR>&nbsp;&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR>};<BR><BR>template&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000">&nbsp;T</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #0000ff">struct</SPAN><SPAN style="COLOR: #000000">&nbsp;Base&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">T,&nbsp;</SPAN><SPAN style="COLOR: #000000">4</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000"><BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">(</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000">FUNC_TYPE)(<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typename&nbsp;TypeAt&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">T,&nbsp;</SPAN><SPAN style="COLOR: #000000">0</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">::Result::OriginalType,&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typename&nbsp;TypeAt&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">T,&nbsp;</SPAN><SPAN style="COLOR: #000000">1</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">::Result::OriginalType,<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typename&nbsp;TypeAt&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">T,&nbsp;</SPAN><SPAN style="COLOR: #000000">2</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">::Result::OriginalType,<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typename&nbsp;TypeAt&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">T,&nbsp;</SPAN><SPAN style="COLOR: #000000">3</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">::Result::OriginalType);<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">&nbsp;async_call&nbsp;(<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typename&nbsp;TypeAt&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">T,&nbsp;</SPAN><SPAN style="COLOR: #000000">0</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">::Result::OriginalType&nbsp;v0,&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typename&nbsp;TypeAt&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">T,&nbsp;</SPAN><SPAN style="COLOR: #000000">1</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">::Result::OriginalType&nbsp;v1,&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typename&nbsp;TypeAt&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">T,&nbsp;</SPAN><SPAN style="COLOR: #000000">2</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">::Result::OriginalType&nbsp;v2,&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typename&nbsp;TypeAt&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">T,&nbsp;</SPAN><SPAN style="COLOR: #000000">3</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">::Result::OriginalType&nbsp;v3,<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FUNC_TYPE&nbsp;func)<BR>&nbsp;&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">&nbsp;async_call&nbsp;(<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typename&nbsp;TypeAt&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">T,&nbsp;</SPAN><SPAN style="COLOR: #000000">0</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">::Result::OriginalType&nbsp;v0,<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typename&nbsp;TypeAt&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">T,&nbsp;</SPAN><SPAN style="COLOR: #000000">1</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">::Result::OriginalType&nbsp;v1,<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typename&nbsp;TypeAt&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">T,&nbsp;</SPAN><SPAN style="COLOR: #000000">2</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">::Result::OriginalType&nbsp;v2,<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typename&nbsp;TypeAt&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">T,&nbsp;</SPAN><SPAN style="COLOR: #000000">3</SPAN><SPAN style="COLOR: #000000">&gt;</SPAN><SPAN style="COLOR: #000000">::Result::OriginalType&nbsp;v3)<BR>&nbsp;&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR>};</SPAN></DIV><BR>这部分有点多，其实还是比较清晰的。注意这个Base的版本已经不是上面所讲的那个了。<BR><BR>函数原形推导问题就讲完了。上面的代码不一定还能编译，昨天是能编译的，被我修改了一些，为了解释，又改成昨天那样子。<img src ="http://www.cppblog.com/cpunion/aggbug/349.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cpunion/" target="_blank">qiezi</a> 2005-09-20 22:34 <a href="http://www.cppblog.com/cpunion/archive/2005/09/20/349.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>正式建立asgard项目 (因ancients已经被人使用了）</title><link>http://www.cppblog.com/cpunion/archive/2005/09/20/327.html</link><dc:creator>qiezi</dc:creator><author>qiezi</author><pubDate>Tue, 20 Sep 2005 02:30:00 GMT</pubDate><guid>http://www.cppblog.com/cpunion/archive/2005/09/20/327.html</guid><wfw:comment>http://www.cppblog.com/cpunion/comments/327.html</wfw:comment><comments>http://www.cppblog.com/cpunion/archive/2005/09/20/327.html#Feedback</comments><slash:comments>16</slash:comments><wfw:commentRss>http://www.cppblog.com/cpunion/comments/commentRss/327.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/cpunion/services/trackbacks/327.html</trackback:ping><description><![CDATA[“为C++实现一个IDL”这个主题，我已经考虑得差不多了，最后几个问题也解决了，打算建立一个项目来实现它。<BR><BR>项目命名为ancients，字面意思是“远古的，旧的”，实际上这个主题也算是旧的了。原本打算命名为C++ Remoting，不过想了一下，还是换个名字，免得让人一看就想拿去跟java, c#的remoting比较。<BR><BR>取这个名字主要是因为喜欢看《星际之门》剧集，里面最喜欢的一个种族就是ancients。<BR><BR>asgard是另一个种族，在ancients这个名字被人占用了的情况下，只好选它了。它的字面意思是“仙宫”，也是不错的名字，呵呵。asgard这个种族的科技非常发达，有先进的亚空间旅行技术，先进的光传送技术，身体也比较符合一些报道中外星人的样子。<BR><BR>暂时还没找到合适的空间来放这个项目，就以压缩包的形式在这个blog上做吧。<BR><BR>打算先实现动态部分，我给它命名为reflection，模仿java的，当然也不会做它那么完整。这部分必须先做，这样方便用来测试静态结构。<BR><BR>然后是静态结构部分，前面已经写了2篇乱七八糟的描述，剩余问题（函数原形推导问题）基本已经解决了。<BR><BR>整个框架在Service以下都是环境无关的，这里的环境指的是协议、通讯等环境。也就是说，定义一个Service，并不在一开始就指定它所使用的通讯协议。定义完成以后，把它指定给一个协议，就可以实现协议绑定，甚至在运行时刻动态切换到另一个协议。当然这可能是不合理的，不过我认为如果支持这种做法，本身就是灵活性的一种体现。<BR><BR><BR><BR>前面还有些地方，和实际情况有些差别的，需要补充完善。简要描述如下：<BR><BR>使用宏来定义Service，前面只定义了方法的原型、名称、服务端绑定的函数，其实还差一个重要的东西，就是参数的名字。<BR>如果使用自己的协议，或者是顺序存储的协议，比如BENCODE，来作为远程调用协议，那么参数的名字是不重要的，只要按顺序把参数序列化、反序列化就可以了。<BR>但在使用SOAP作为远程调用协议时，就得考虑为参数加上名字了，SOAP是从XML元素中，按参数名称来提取参数值的，虽然我们可以为参数生成一个名字，但这个名字不能描述参数所表达的意思。<BR>所以需要考虑为参数取上名字。<BR><BR>暂时就补充这一点，其它方面有等进一步研究。<img src ="http://www.cppblog.com/cpunion/aggbug/327.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cpunion/" target="_blank">qiezi</a> 2005-09-20 10:30 <a href="http://www.cppblog.com/cpunion/archive/2005/09/20/327.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>为C＋＋实现一个IDL　（一）</title><link>http://www.cppblog.com/cpunion/archive/2005/09/17/284.html</link><dc:creator>qiezi</dc:creator><author>qiezi</author><pubDate>Sat, 17 Sep 2005 11:40:00 GMT</pubDate><guid>http://www.cppblog.com/cpunion/archive/2005/09/17/284.html</guid><wfw:comment>http://www.cppblog.com/cpunion/comments/284.html</wfw:comment><comments>http://www.cppblog.com/cpunion/archive/2005/09/17/284.html#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://www.cppblog.com/cpunion/comments/commentRss/284.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/cpunion/services/trackbacks/284.html</trackback:ping><description><![CDATA[<P>前面简单写了点静态结构，这一次将主要关注动态模型以及调用方式。</P>
<P>这个系列的名字叫“为C++实现一个IDL”，实际上应该叫“为C++实现一个Remoting”可能更好一些，说是IDL，主要是想通过宏，使用简单的类型定义达到自动生成调用代码的目的。</P>
<P><STRONG>一、首先来看看调用习惯。</STRONG></P>
<P>从调用习惯入手，主要是因为看到目前有很多库/工具包在调用上都有很多不便之处。假如能在一开始就从这点出发，就能把调用接口设计得更好一些。</P>
<P>先来看看服务端如何开放一个服务。</P>
<DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000"> main ()<BR>{<BR>    </SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000"> 发布为SOAP服务，先生成一个服务容器。<BR>    </SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000"> 服务将发布在localhost的7911上，localhost用来绑定loopback网卡。</SPAN><SPAN style="COLOR: #008000"><BR></SPAN><SPAN style="COLOR: #000000">    SOAPProxy soap_service (</SPAN><SPAN style="COLOR: #000000">7911</SPAN><SPAN style="COLOR: #000000">, “localhost”);<BR><BR>    TestService test_service; <BR>    soap_service.addService  (“test_service”, </SPAN><SPAN style="COLOR: #000000">&</SPAN><SPAN style="COLOR: #000000">test_service);<BR><BR>    TestService service1;<BR>    soap_service.addService (“HelloService”, </SPAN><SPAN style="COLOR: #000000">&</SPAN><SPAN style="COLOR: #000000">service1);<BR><BR>    </SPAN><SPAN style="COLOR: #0000ff">try</SPAN><SPAN style="COLOR: #000000">{<BR>        soap_service.run ();<BR>    } </SPAN><SPAN style="COLOR: #0000ff">catch</SPAN><SPAN style="COLOR: #000000"> (SocketException</SPAN><SPAN style="COLOR: #000000">&</SPAN><SPAN style="COLOR: #000000"> e)<BR>    {<BR>    } </SPAN><SPAN style="COLOR: #0000ff">catch</SPAN><SPAN style="COLOR: #000000"> (SignalException</SPAN><SPAN style="COLOR: #000000">&</SPAN><SPAN style="COLOR: #000000"> e)<BR>    {<BR>    }<BR><BR>    </SPAN><SPAN style="COLOR: #0000ff">return</SPAN><SPAN style="COLOR: #000000"> </SPAN><SPAN style="COLOR: #000000">0</SPAN><SPAN style="COLOR: #000000">;<BR>}</SPAN></DIV>
<P><BR>我希望就是这么简单，客户端调用有多种方式：<BR>1、 使用服务的IDL定义，直接调用：</P>
<DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000"> main ()<BR>{<BR>    SOAPProxy soap_service (</SPAN><SPAN style="COLOR: #000000">7911</SPAN><SPAN style="COLOR: #000000">, “localhost”);<BR><BR>    </SPAN><SPAN style="COLOR: #0000ff">try</SPAN><SPAN style="COLOR: #000000">{<BR>        TestService test_service (“test_service”, </SPAN><SPAN style="COLOR: #000000">&</SPAN><SPAN style="COLOR: #000000">soap_service);<BR>        test_service.method1 (</SPAN><SPAN style="COLOR: #008000">/*</SPAN><SPAN style="COLOR: #008000"><IMG src="http://www.cppblog.com/images/dot.gif"></SPAN><SPAN style="COLOR: #008000">*/</SPAN><SPAN style="COLOR: #000000">);<BR>    } </SPAN><SPAN style="COLOR: #0000ff">catch</SPAN><SPAN style="COLOR: #000000"> (SocketException</SPAN><SPAN style="COLOR: #000000">&</SPAN><SPAN style="COLOR: #000000"> e)<BR>    {<BR>    }<BR>    </SPAN><SPAN style="COLOR: #0000ff">return</SPAN><SPAN style="COLOR: #000000"> </SPAN><SPAN style="COLOR: #000000">0</SPAN><SPAN style="COLOR: #000000">;<BR>}</SPAN></DIV>
<P><BR>这种方式比较简单，调用时会检查是否已经连接，然后发送调用请求，并处理调用结果。</P>
<P>2、 服务验证方式：</P>
<DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000"> main ()<BR>{<BR>    SOAPProxy soap_service (</SPAN><SPAN style="COLOR: #000000">7911</SPAN><SPAN style="COLOR: #000000">, “localhost”);<BR>    TestService test_service;<BR>    soap_service.getService (“test_service”, </SPAN><SPAN style="COLOR: #000000">&</SPAN><SPAN style="COLOR: #000000">test_service);<BR><BR>    </SPAN><SPAN style="COLOR: #0000ff">if</SPAN><SPAN style="COLOR: #000000"> (test_service)<BR>    {<BR>        </SPAN><SPAN style="COLOR: #0000ff">try</SPAN><SPAN style="COLOR: #000000">{<BR>            test_service.method1 (</SPAN><SPAN style="COLOR: #008000">/*</SPAN><SPAN style="COLOR: #008000"><IMG src="http://www.cppblog.com/images/dot.gif"></SPAN><SPAN style="COLOR: #008000">*/</SPAN><SPAN style="COLOR: #000000">);<BR>        } </SPAN><SPAN style="COLOR: #0000ff">catch</SPAN><SPAN style="COLOR: #000000"> (SocketException</SPAN><SPAN style="COLOR: #000000">&</SPAN><SPAN style="COLOR: #000000"> e)<BR>        {<BR>        }<BR>    }<BR>    </SPAN><SPAN style="COLOR: #0000ff">return</SPAN><SPAN style="COLOR: #000000"> </SPAN><SPAN style="COLOR: #000000">0</SPAN><SPAN style="COLOR: #000000">;<BR>}</SPAN></DIV>
<P><BR>3、 服务发现方式：</P>
<DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000"> main ()<BR>{<BR>    SOAPProxy soap_service (</SPAN><SPAN style="COLOR: #000000">7911</SPAN><SPAN style="COLOR: #000000">, “localhost”);<BR>    vector </SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">string</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000"> services_name </SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000"> soap_service.getServiceNames ();<BR>    </SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000"> <IMG src="http://www.cppblog.com/images/dot.gif"></SPAN><SPAN style="COLOR: #008000"><BR></SPAN><SPAN style="COLOR: #000000">    IService</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000"> test_service </SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000"> soap_service.getService (“test_service”);<BR>    </SPAN><SPAN style="COLOR: #0000ff">if</SPAN><SPAN style="COLOR: #000000"> (test_service)<BR>    {<BR>        vector </SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">string</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000"> methods </SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000"> test_service</SPAN><SPAN style="COLOR: #000000">-></SPAN><SPAN style="COLOR: #000000">getMethodNames ();<BR>        IMethod</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000"> method </SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000"> test_service</SPAN><SPAN style="COLOR: #000000">-></SPAN><SPAN style="COLOR: #000000">getMethod (“method1”);<BR>        vector </SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #000000">Type</SPAN><SPAN style="COLOR: #000000">*></SPAN><SPAN style="COLOR: #000000"> types </SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000"> method</SPAN><SPAN style="COLOR: #000000">-></SPAN><SPAN style="COLOR: #000000">getParameterType s()<BR>        method</SPAN><SPAN style="COLOR: #000000">-></SPAN><SPAN style="COLOR: #000000">addArg (</SPAN><SPAN style="COLOR: #000000">3</SPAN><SPAN style="COLOR: #000000">);<BR>        method</SPAN><SPAN style="COLOR: #000000">-></SPAN><SPAN style="COLOR: #000000">addArg (</SPAN><SPAN style="COLOR: #000000">4</SPAN><SPAN style="COLOR: #000000">);<BR>        </SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000"> <IMG src="http://www.cppblog.com/images/dot.gif"></SPAN><SPAN style="COLOR: #008000"><BR></SPAN><SPAN style="COLOR: #000000">        method</SPAN><SPAN style="COLOR: #000000">-></SPAN><SPAN style="COLOR: #000000">invoke ();<BR>        </SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000"> <IMG src="http://www.cppblog.com/images/dot.gif"></SPAN><SPAN style="COLOR: #008000"><BR></SPAN><SPAN style="COLOR: #000000">    }<BR>    </SPAN><SPAN style="COLOR: #0000ff">return</SPAN><SPAN style="COLOR: #000000"> </SPAN><SPAN style="COLOR: #000000">0</SPAN><SPAN style="COLOR: #000000">;<BR>}</SPAN></DIV>
<P><STRONG><BR>二、基本需求。<BR><BR></STRONG>简单分析一下，上面一共涉及了哪些类型？<BR>IProxy:<BR>这是所有Proxy类的基类(和接口)，它可以容纳多个服务对象，提供服务绑定、服务查询、服务发现、服务验证。<BR>IService:<BR>所有Service类的基类，可以容纳多个方法(Method)，提供方法查询、服务验证。<BR>IMethod:<BR>所有Method模板类的基类，容纳多个参数，包括返回值，可通过查询参数类型获得方法的类型定义。<BR>IParameter:<BR>所有参数的基类，包含一个参数类型描述和一个参数值。<BR>IType:<BR>所有类型的基类，预定义了一些基本类型，可自定义类型。</P>
<P>看起来挺多的，其实很难接触到这些，只需要使用宏来定义一个服务，就可以通过模板的类型推导，自动生成这些复杂的定义。</P><STRONG>三、调用过程。<BR><BR></STRONG>以下只简单分析一下同步调用，异步调用将是以后的扩充话题。<BR>根据第二节的3种不同调用过程，简要描述如下： 
<OL>
<LI>直接调用。<BR><BR>
<UL>
<LI>生成SOAPProxy，让它连接到远程主机。<BR>
<LI>生成一个TestService对象，设置远程主机上的服务名称，并指定使用SOAPProxy，也即使用SOAP协议。<BR>
<LI>调用TestService::method1方法。根据method1的定义，把服务名称、方法名称、各个in参数等打包成一个“集合”，交给SOAPProxy处理。<BR>
<LI>SOAPProxy把这个“集合”转换成SOAP消息，发送到远程主机，阻塞线程。<BR>
<LI>远程主机上的SOAPProxy对象收到数据，进行解析。当解析出一个服务调用时，把它交给TestService服务处理。<BR>
<LI>TestService解析出一个方法调用，把它交给Method处理。<BR>
<LI>Method解析出各个参数，验证参数类型、完整性等，并执行调用或返回错误。<BR>
<LI>Method调用的返回信息(包括调用结果、返回值、out参数等)被打包成一个“集合”，交给TestService处理。<BR>
<LI>TestService处理后，交给SOAPProxy。<BR>
<LI>SOAPProxy把结果打包成SOAP消息，发回调用端。<BR>
<LI>调用端解析SOAP消息，把OUT参数值赋给调用者提供的对象，调用完成。 </LI></UL>
<P> </P>
<LI>服务验证方式。<BR>
<UL>
<LI>生成SOAPProxy，让它连接到远程主机。<BR>
<LI>生成TestService对象，调用SOAPProxy的getService验证版本。<BR>
<LI>SOAPProxy把TestService对象的信息(名称、成员及基类型等)发送到远程主机，阻塞。<BR>
<LI>远程主机解析收到的信息，查找服务名，并比较查找到的服务类型与解析得到的类型。<BR>
<LI>比较结果发回给调用端。<BR>
<LI>调用端接着采用直接调用的方式，调用远程服务。</LI></UL><BR>这种方式看起来多了一些操作，不过验证的好处是能够减少调用时的异常。 
<P></P>
<LI>服务发现方式。<BR>
<UL>
<LI>生成SOAPProxy，让它连接到远程主机。<BR>
<LI>查询远程开放的服务名称。(可省略)<BR>
<LI>查找特定服务，得到服务描述信息。<BR>
<LI>查找服务中的方法，得到方法描述信息。<BR>
<LI>压入各个参数，并执行调用。<BR>
<LI>调用前先判断参数是否与描述一致，然后调用SOAPProxy生成SOAP消息，发送到远程主机，阻塞。<BR>
<LI>远程主机解析出调用。。。后面过程与第1种方式相同，远程主机并不知道客户端使用的是哪种方式来调用。远程主机处理结束，将返回SOAP消息给调用端。<BR>
<LI>调用端解析出调用结果，并把各个OUT参数的值赋给method对象。</LI></UL><BR>使用这种方式，调用端不需要服务的类型定义。 
<P></P></LI></OL>
<P><STRONG>四、异步调用/异步分派(AMI/AMD)。<BR></STRONG><BR>同步调用时，调用端线程需要等待调用结果，服务端线程也要等待调用结束返回，才处理下一个调用。<BR>为了在服务调用期间让线程能做更多的事：<BR>调用端把调用交给线程池完成，并在调用完成后采用某种机制通知线程处理结果，或者直接由线程池中的调用线程调用结果处理函数。这种方式称为AMI(异步方法调用)。<BR>服务端主线程则把接收到的消息解析后，放入处理队列，由线程池去处理调用过程。当调用完成后，结果放入结果队列，由主线程处理成消息，发送回调用端。这种方式称为AMD(异步方法分派)。<BR>调用端和服务端依旧是使用通讯协议来沟通，双方都不知道对方是否采用了异步方式。</P>
<P>AMI和AMD对于静态定义的服务是有影响的，比如下面一个服务：</P>
<DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><SPAN style="COLOR: #0000ff">struct</SPAN><SPAN style="COLOR: #000000"> TestService<BR>{<BR>    Method </SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">(</SPAN><SPAN style="COLOR: #0000ff">in</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">, </SPAN><SPAN style="COLOR: #0000ff">out</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">)</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000"> method1;<BR>}</SPAN></DIV>
<P><BR>在同步调用时，它的调用方式：</P>
<DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><SPAN style="COLOR: #000000">TestService test_service;<BR></SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000"> a;<BR>service.method1 (</SPAN><SPAN style="COLOR: #000000">3</SPAN><SPAN style="COLOR: #000000">, a); </SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000"> 或者 service.method1 (3, &a)，打算兼容这2种方式。</SPAN></DIV>
<P><BR>异步调用时，调用方式：</P>
<DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000"> method1_result (</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">, </SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">);<BR>TestService test_service;<BR>test_service.method1.async_call(</SPAN><SPAN style="COLOR: #000000">3</SPAN><SPAN style="COLOR: #000000">, method1_result); </SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000"> 调用完成后，让调用线程去调用method1_result通知调用结果。<BR></SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000"> 或者像下面</SPAN><SPAN style="COLOR: #008000"><BR></SPAN><SPAN style="COLOR: #000000">IMethod</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000"> result </SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000"> test_service.method1.async_call (</SPAN><SPAN style="COLOR: #000000">3</SPAN><SPAN style="COLOR: #000000">);<BR></SPAN><SPAN style="COLOR: #0000ff">while</SPAN><SPAN style="COLOR: #000000"> (</SPAN><SPAN style="COLOR: #000000">!</SPAN><SPAN style="COLOR: #000000">result</SPAN><SPAN style="COLOR: #000000">-></SPAN><SPAN style="COLOR: #000000">done())  </SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000"> 还有很多好办法，这里只是为了简单。</SPAN><SPAN style="COLOR: #008000"><BR></SPAN><SPAN style="COLOR: #000000">{<BR>    sleep (</SPAN><SPAN style="COLOR: #000000">1</SPAN><SPAN style="COLOR: #000000">);<BR>}<BR>cout </SPAN><SPAN style="COLOR: #000000"><<</SPAN><SPAN style="COLOR: #000000"> result</SPAN><SPAN style="COLOR: #000000">-></SPAN><SPAN style="COLOR: #000000">getArg(</SPAN><SPAN style="COLOR: #000000">1</SPAN><SPAN style="COLOR: #000000">)</SPAN><SPAN style="COLOR: #000000">-></SPAN><SPAN style="COLOR: #000000">toInt(); <BR></SPAN></DIV>
<P><BR>正如上面演示的一样，异步调用的结果有2种方式去处理。<BR>一是由线程池调用完以后，接着调用一个函数以通知结果。它不需要轮询，不过涉及到了线程问题，增加了一些复杂性。<BR>另一种方式调用结束后，原调用线程在某个适当的“时机”去查询调用结果。这个时机可以是定时查询，也可以是被线程消息通知而去处理。</P>
<P><STRONG>五、其它。<BR></STRONG><BR>这一篇加上前一篇，应该是提到了全部的要点。<BR>目前剩下的唯一一个难点，可能是在处理异步调用时，Method的定义。<BR>正如上面演示的，一个方法在同步调用和异步调用时，就有3种调用方式：</P>
<DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><SPAN style="COLOR: #000000">service.method1 (</SPAN><SPAN style="COLOR: #000000">3</SPAN><SPAN style="COLOR: #000000">, a);<BR>test_service.method1.async_call(</SPAN><SPAN style="COLOR: #000000">3</SPAN><SPAN style="COLOR: #000000">, method1_result);<BR>IMethod</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000"> result </SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000"> test_service.method1.async_call (</SPAN><SPAN style="COLOR: #000000">3</SPAN><SPAN style="COLOR: #000000">);</SPAN></DIV>
<P><BR>特别地，它如何根据in和个数和out的个数，产生那2个参数个数匹配的异步调用函数？<BR>再来回顾一下method1的定义：</P>
<DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><SPAN style="COLOR: #000000">Method </SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">(</SPAN><SPAN style="COLOR: #0000ff">in</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">, </SPAN><SPAN style="COLOR: #0000ff">out</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">)</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000"> method1;</SPAN></DIV>
<P><BR>显然有一定的复杂性，不过我认为还是可以处理掉的。拿3个参数的偏特化版本来说明：</P>
<DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><SPAN style="COLOR: #000000">template </SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000"> Ret, </SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000"> A, </SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000"> B, </SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000"> C</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000"> Method </SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #000000">Out</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #000000">Ret</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">(A,B,C)</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000"> : </SPAN><SPAN style="COLOR: #0000ff">public</SPAN><SPAN style="COLOR: #000000"> MethodBase </SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #000000">Out</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #000000">Ret</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">,A,B,C</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000"><BR>{<BR>};<BR><BR>template </SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000"> Ret</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">NullType, </SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000"> A</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">NullType, </SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000"> B</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">NullType, </SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000"> C</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">NullType, </SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000"> D</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">NullType, IN_COUNT</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">InCount</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #000000"> A,B,C,D</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">::value </SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000"> MethodBase<BR>{<BR>};<BR><BR></SPAN></DIV>
<P><BR>通过对MethodBase类的IN＿COUNT参数定义偏特化，即可定义出这些不同的版本。<BR><BR>当然仅仅是知道了IN参数的个数，还没有提取出IN参数的类型，所以还不能生成函数的原型，或许需要把typelist加进来了（loki中的那个）。<BR><BR><BR><BR>这是后面要考虑的内容，今天先想到这。</P><img src ="http://www.cppblog.com/cpunion/aggbug/284.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cpunion/" target="_blank">qiezi</a> 2005-09-17 19:40 <a href="http://www.cppblog.com/cpunion/archive/2005/09/17/284.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>为C＋＋实现一个IDL　（零）</title><link>http://www.cppblog.com/cpunion/archive/2005/09/15/272.html</link><dc:creator>qiezi</dc:creator><author>qiezi</author><pubDate>Wed, 14 Sep 2005 17:27:00 GMT</pubDate><guid>http://www.cppblog.com/cpunion/archive/2005/09/15/272.html</guid><wfw:comment>http://www.cppblog.com/cpunion/comments/272.html</wfw:comment><comments>http://www.cppblog.com/cpunion/archive/2005/09/15/272.html#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://www.cppblog.com/cpunion/comments/commentRss/272.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/cpunion/services/trackbacks/272.html</trackback:ping><description><![CDATA[<P>一、问题。<BR><BR>这段时间考虑实现一个纯C＋＋的分布式服务包装库，简要描述如下：</P>
<P>有如下类和函数：</P>
<DIV style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 0.5pt solid; PADDING-LEFT: 5.4pt; BACKGROUND: #e6e6e6; PADDING-BOTTOM: 4px; BORDER-LEFT: windowtext 0.5pt solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: windowtext 0.5pt solid">
<DIV><SPAN style="COLOR: #0000ff">struct</SPAN><SPAN style="COLOR: #000000"> Test<BR>{<BR>    </SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000"> test1 (</SPAN><SPAN style="COLOR: #008000">/*</SPAN><SPAN style="COLOR: #008000">in</SPAN><SPAN style="COLOR: #008000">*/</SPAN><SPAN style="COLOR: #000000"> </SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000"> v1, </SPAN><SPAN style="COLOR: #008000">/*</SPAN><SPAN style="COLOR: #008000">in</SPAN><SPAN style="COLOR: #008000">*/</SPAN><SPAN style="COLOR: #000000"> </SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000"> v2);<BR>    </SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000"> test2 (</SPAN><SPAN style="COLOR: #008000">/*</SPAN><SPAN style="COLOR: #008000">in</SPAN><SPAN style="COLOR: #008000">*/</SPAN><SPAN style="COLOR: #000000"> </SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&</SPAN><SPAN style="COLOR: #000000"> v1, </SPAN><SPAN style="COLOR: #008000">/*</SPAN><SPAN style="COLOR: #008000">out</SPAN><SPAN style="COLOR: #008000">*/</SPAN><SPAN style="COLOR: #000000"> </SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000"> v2);<BR>};<BR><BR></SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000"> test_func (</SPAN><SPAN style="COLOR: #008000">/*</SPAN><SPAN style="COLOR: #008000">in</SPAN><SPAN style="COLOR: #008000">*/</SPAN><SPAN style="COLOR: #000000"> </SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000"> v1, </SPAN><SPAN style="COLOR: #008000">/*</SPAN><SPAN style="COLOR: #008000">inout</SPAN><SPAN style="COLOR: #008000">*/</SPAN><SPAN style="COLOR: #000000"> </SPAN><SPAN style="COLOR: #0000ff">string</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000"> v2);</SPAN></DIV></DIV>
<P><BR>想把它们作为服务发布出去，以SOAP或其它方式。发布为一个TestService，并让它携带多一些信息:</P>
<DIV style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 0.5pt solid; PADDING-LEFT: 5.4pt; BACKGROUND: #e6e6e6; PADDING-BOTTOM: 4px; BORDER-LEFT: windowtext 0.5pt solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: windowtext 0.5pt solid">
<DIV><SPAN style="COLOR: #0000ff">struct</SPAN><SPAN style="COLOR: #000000"> TestService<BR>{<BR>    </SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000"> test1 (</SPAN><SPAN style="COLOR: #0000ff">in</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000"> v1, </SPAN><SPAN style="COLOR: #0000ff">in</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000"> v2);<BR>    </SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000"> test2 (</SPAN><SPAN style="COLOR: #0000ff">in</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000"> v1, </SPAN><SPAN style="COLOR: #0000ff">out</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000"> v2);<BR>    </SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000"> test_func (</SPAN><SPAN style="COLOR: #0000ff">in</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000"> v1, inout</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">string</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000"> v2);<BR>};</SPAN></DIV></DIV>
<P><BR>C＋＋有许多工具、库来做到这点，但是，都需要生成一堆代码，很是不爽。<BR><BR>其它语言，比如python, java, c#等，都可以通过自省机制，抛开IDL在语言内实现。<BR><BR>C＋＋并非不能做这个，它只是缺少足够的类型信息。比如上面的例子，如果要发布为服务，那么至少应该把它的参数、返回值搞得明确些，否则要么会造成不必要的参数传递，要么会产生错误（把OUT参数取值可不是安全的）。<BR><BR>比如上面出现的int, int&, int*，在作为in参数时，我们是想传递它的值，类型为int。而int*和string*作为out参数时，我们想让它传递指针或引用，当调用返回时，我们给它赋值。<BR><BR>C＋＋语言的类型极为丰富，却没有描述一个参数到底是in还是out。java也没有，但它可以正常序列化一个null值，在C＋＋中，这可能存在一些麻烦。<BR><BR>再考虑一下char*类型，假如它是in参数，那么它是要传递一个字符还是一个字符串？C＋＋语言没有对它进行描述。<BR><BR>所以要实现一个分布式服务包装（或代理）库，必须让发布者提供这些信息。<BR><BR>我们知道，要查询一个远程服务，必须查询相应主机端口，获取服务信息。最简单的服务信息包括：服务列表，每个服务中的方法列表，方法的类型（包括参数和返回值类型，in/out信息等）。<BR><BR>实际上，我们是要为C＋＋增加一些简单的自省能力。上面那个服务发布接口，实际上离这个要求还有很远，再来看一下：</P>
<DIV style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 0.5pt solid; PADDING-LEFT: 5.4pt; BACKGROUND: #e6e6e6; PADDING-BOTTOM: 4px; BORDER-LEFT: windowtext 0.5pt solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: windowtext 0.5pt solid">
<DIV><SPAN style="COLOR: #0000ff">struct</SPAN><SPAN style="COLOR: #000000"> TestService<BR>{<BR>    </SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000"> test1 (</SPAN><SPAN style="COLOR: #0000ff">in</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000"> v1, </SPAN><SPAN style="COLOR: #0000ff">in</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000"> v2);<BR>    </SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000"> test2 (</SPAN><SPAN style="COLOR: #0000ff">in</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000"> v1, </SPAN><SPAN style="COLOR: #0000ff">out</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000"> v2);<BR>    </SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000"> test_func (</SPAN><SPAN style="COLOR: #0000ff">in</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000"> v1, inout</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">string</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000"> v2);<BR>};</SPAN></DIV></DIV>
<P><BR>可以想见，它是没有一点自省能力的，我们如何向它查询，它的名字？它的方法列表？方法的类型？它如何与Test类的成员函数以及test_func函数关联？</P>
<P>二、方向。<BR><BR>要让上面那个服务具有自省能力，要做的扩充其实并不多。考虑下面的代码：</P>
<DIV style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 0.5pt solid; PADDING-LEFT: 5.4pt; BACKGROUND: #e6e6e6; PADDING-BOTTOM: 4px; BORDER-LEFT: windowtext 0.5pt solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: windowtext 0.5pt solid">
<DIV><SPAN style="COLOR: #0000ff">struct</SPAN><SPAN style="COLOR: #000000"> TestService : </SPAN><SPAN style="COLOR: #0000ff">public</SPAN><SPAN style="COLOR: #000000"> Service<BR>{<BR>    TestService ();<BR>    Method </SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">(</SPAN><SPAN style="COLOR: #0000ff">in</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">, </SPAN><SPAN style="COLOR: #0000ff">in</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">)</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000"> test1;<BR>    Method </SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">(</SPAN><SPAN style="COLOR: #0000ff">in</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">, </SPAN><SPAN style="COLOR: #0000ff">out</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">)</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000"> test2;<BR>    Method </SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">(</SPAN><SPAN style="COLOR: #0000ff">in</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">, inout</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">string</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">) test_func;<BR>};</SPAN></DIV></DIV>
<P><BR>这几个Method可以用自己写的委托类来做。<BR><BR>1、假如我们在TestService的构造函数里给它分配一个“TestService”名字，并且Service类实现了查询名字的接口，那么它就知道它自己的名字了。<BR><BR>2、假如在TestService的构造函数里为各个Method分配名字，并且注册到TestService，那么它就能够查询方法列表。<BR><BR>3、方法的类型？通过模板方式，把各个参数类型收集起来，给个字符串名称就可以了。<BR><BR>使用宏来实现，大概可以写成这样：<BR><BR></P>
<P></P>
<DIV style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 0.5pt solid; PADDING-LEFT: 5.4pt; BACKGROUND: #e6e6e6; PADDING-BOTTOM: 4px; BORDER-LEFT: windowtext 0.5pt solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: windowtext 0.5pt solid">
<DIV><SPAN style="COLOR: #000000">BEGIN_SERVICE (TestService)<BR>    METHOD (</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">(</SPAN><SPAN style="COLOR: #0000ff">in</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">, </SPAN><SPAN style="COLOR: #0000ff">in</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">), test1, </SPAN><SPAN style="COLOR: #000000">&</SPAN><SPAN style="COLOR: #000000">Test::test1)<BR>    METHOD (</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">(</SPAN><SPAN style="COLOR: #0000ff">in</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">, </SPAN><SPAN style="COLOR: #0000ff">out</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">), test2, </SPAN><SPAN style="COLOR: #000000">&</SPAN><SPAN style="COLOR: #000000">Test::test2)<BR>    METHOD (</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">in</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">, inout</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">string</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">), test_func, test_func)<BR>END_SERVICE ()</SPAN></DIV></DIV>
<P><BR>通过上面这几个宏，我们能够生成TestService声明。<BR><BR>不过，有几个问题，罗列如下，并一一解决它：<BR><BR>1、如何把函数指针传给它？如何把方法名称传给它？<BR>这个只是C＋＋语言为我们增加了一些麻烦，我们无法在定义成员的地方调用它的构造函数，不过这并不会造成多大障碍。<BR>上面的METHOD宏如果只是生成类的声明，那么函数指针可以省略。我把它加上的原因是，它可以被我用Ctrl+C, Ctrl+V这种世界上最先进的技术原样拷贝下来，并且通过简单修改的方法实现这种世界上最先进的重用。<BR><BR>上面的代码经过修改，结果就成这样：</P>
<DIV style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 0.5pt solid; PADDING-LEFT: 5.4pt; BACKGROUND: #e6e6e6; PADDING-BOTTOM: 4px; BORDER-LEFT: windowtext 0.5pt solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: windowtext 0.5pt solid">
<DIV><SPAN style="COLOR: #000000">BEGIN_SERVICE (TestService)<BR>    METHOD (</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">(</SPAN><SPAN style="COLOR: #0000ff">in</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">, </SPAN><SPAN style="COLOR: #0000ff">in</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">), test1, </SPAN><SPAN style="COLOR: #000000">&</SPAN><SPAN style="COLOR: #000000">Test::test1)<BR>    METHOD (</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">(</SPAN><SPAN style="COLOR: #0000ff">in</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">, </SPAN><SPAN style="COLOR: #0000ff">out</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">), test2, </SPAN><SPAN style="COLOR: #000000">&</SPAN><SPAN style="COLOR: #000000">Test::test2)<BR>    METHOD (</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">in</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">, inout</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">string</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">), test_func, test_func)<BR><BR>    BEGIN_DEFINE (TestService)<BR>        METHOD_DEFINE (</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">(</SPAN><SPAN style="COLOR: #0000ff">in</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">, </SPAN><SPAN style="COLOR: #0000ff">in</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">), test1, </SPAN><SPAN style="COLOR: #000000">&</SPAN><SPAN style="COLOR: #000000">Test::test1)<BR>        METHOD_DEFINE(</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">(</SPAN><SPAN style="COLOR: #0000ff">in</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">, </SPAN><SPAN style="COLOR: #0000ff">out</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">), test2, </SPAN><SPAN style="COLOR: #000000">&</SPAN><SPAN style="COLOR: #000000">Test::test2)<BR>        METHOD_DEFINE(</SPAN><SPAN style="COLOR: #0000ff">int(</SPAN><SPAN style="COLOR: #0000ff">in</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">, inout</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">string</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">), test_func, test_func)<BR>    END_DEFINE ()<BR><BR>END_SERVICE ()</SPAN></DIV></DIV>
<P><BR>看上去对应得非常整齐，修改起来也比较简单。上面那部分被扩充为如下代码：</P>
<DIV style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 0.5pt solid; PADDING-LEFT: 5.4pt; BACKGROUND: #e6e6e6; PADDING-BOTTOM: 4px; BORDER-LEFT: windowtext 0.5pt solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: windowtext 0.5pt solid">
<DIV><SPAN style="COLOR: #0000ff">struct</SPAN><SPAN style="COLOR: #000000"> TestService : </SPAN><SPAN style="COLOR: #0000ff">public</SPAN><SPAN style="COLOR: #000000"> Service<BR>{<BR>    Method </SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">(</SPAN><SPAN style="COLOR: #0000ff">in</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">, </SPAN><SPAN style="COLOR: #0000ff">in</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">)</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000"> test1;<BR>    Method </SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">(</SPAN><SPAN style="COLOR: #0000ff">in</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">, </SPAN><SPAN style="COLOR: #0000ff">out</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">)</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000"> test2;<BR>    Method </SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">(</SPAN><SPAN style="COLOR: #0000ff">in</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">, inout</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">string</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">) test_func;<BR>    TestService ()<BR>    : Service (</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">TestService</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">)<BR>    {<BR>        test1.setName (</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">test1</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">);<BR>        test1.setMethod (</SPAN><SPAN style="COLOR: #000000">&</SPAN><SPAN style="COLOR: #000000">Test::test1);<BR>        </SPAN><SPAN style="COLOR: #0000ff">this</SPAN><SPAN style="COLOR: #000000">-></SPAN><SPAN style="COLOR: #000000">registerMethod (</SPAN><SPAN style="COLOR: #000000">&</SPAN><SPAN style="COLOR: #000000">test1);<BR>        test2.setName (</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">test2</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">);<BR>        test2.setMethod (</SPAN><SPAN style="COLOR: #000000">&</SPAN><SPAN style="COLOR: #000000">Test::test2);<BR>        </SPAN><SPAN style="COLOR: #0000ff">this</SPAN><SPAN style="COLOR: #000000">-></SPAN><SPAN style="COLOR: #000000">registerMethod (</SPAN><SPAN style="COLOR: #000000">&</SPAN><SPAN style="COLOR: #000000">test2);<BR>        test_func.setName (</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">test_func</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">);<BR>        test_func.setMethod (test_func);<BR>        </SPAN><SPAN style="COLOR: #0000ff">this</SPAN><SPAN style="COLOR: #000000">-></SPAN><SPAN style="COLOR: #000000">registerMethod (</SPAN><SPAN style="COLOR: #000000">&</SPAN><SPAN style="COLOR: #000000">test3);<BR>    }<BR>};</SPAN></DIV></DIV>
<P><BR>基本上需要的东西都在这里了。<BR><BR>2、客户端的问题。<BR></P>
<P>上面这种映射，直接拿到客户端会有问题，Test类和test_func函数我们并不打算交给客户端，所以使用函数指针会出现链接错误。<BR><BR>实际上客户端不需要这个，我们想办法把它拿掉就行了。客户端实际需要生成的代码如下：<BR><BR></P>
<DIV style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 0.5pt solid; PADDING-LEFT: 5.4pt; BACKGROUND: #e6e6e6; PADDING-BOTTOM: 4px; BORDER-LEFT: windowtext 0.5pt solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: windowtext 0.5pt solid">
<DIV><SPAN style="COLOR: #0000ff">struct</SPAN><SPAN style="COLOR: #000000"> TestService : </SPAN><SPAN style="COLOR: #0000ff">public</SPAN><SPAN style="COLOR: #000000"> Service<BR>{<BR>    Method </SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">(</SPAN><SPAN style="COLOR: #0000ff">in</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">, </SPAN><SPAN style="COLOR: #0000ff">in</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">)</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000"> test1;<BR>    Method </SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">(</SPAN><SPAN style="COLOR: #0000ff">in</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">, </SPAN><SPAN style="COLOR: #0000ff">out</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">)</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000"> test2;<BR>    Method </SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">(</SPAN><SPAN style="COLOR: #0000ff">in</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">, inout</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">string</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">) test_func;<BR>    TestService ()<BR>    : Service (</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">TestService</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">)<BR>    {<BR>        test1.setName (</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">test1</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">);<BR>        </SPAN><SPAN style="COLOR: #0000ff">this</SPAN><SPAN style="COLOR: #000000">-></SPAN><SPAN style="COLOR: #000000">registerMethod (</SPAN><SPAN style="COLOR: #000000">&</SPAN><SPAN style="COLOR: #000000">test1);<BR>        test2.setName (</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">test2</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">);<BR>        </SPAN><SPAN style="COLOR: #0000ff">this</SPAN><SPAN style="COLOR: #000000">-></SPAN><SPAN style="COLOR: #000000">registerMethod (</SPAN><SPAN style="COLOR: #000000">&</SPAN><SPAN style="COLOR: #000000">test2);<BR>        test_func.setName (</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">test_func</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">);<BR>        </SPAN><SPAN style="COLOR: #0000ff">this</SPAN><SPAN style="COLOR: #000000">-></SPAN><SPAN style="COLOR: #000000">registerMethod (</SPAN><SPAN style="COLOR: #000000">&</SPAN><SPAN style="COLOR: #000000">test3);<BR>    }<BR>};</SPAN></DIV></DIV>
<P><BR>还是上面提到的，C++给我们带来的麻烦。这次需要另一组宏来完成它：</P>
<DIV style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 0.5pt solid; PADDING-LEFT: 5.4pt; BACKGROUND: #e6e6e6; PADDING-BOTTOM: 4px; BORDER-LEFT: windowtext 0.5pt solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: windowtext 0.5pt solid">
<DIV><SPAN style="COLOR: #000000">BEGIN_SERVICE_D (TestService)<BR>    METHOD_D (</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">(</SPAN><SPAN style="COLOR: #0000ff">in</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">, </SPAN><SPAN style="COLOR: #0000ff">in</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">), test1)<BR>    METHOD_D (</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">(</SPAN><SPAN style="COLOR: #0000ff">in</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">, </SPAN><SPAN style="COLOR: #0000ff">out</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">), test2)<BR>    METHOD_D (</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">(</SPAN><SPAN style="COLOR: #0000ff">in</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">, inout</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">string</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">), test_func)<BR><BR>    BEGIN_DEFINE_D (TestService)<BR>        METHOD_DEFINE_D (</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">(</SPAN><SPAN style="COLOR: #0000ff">in</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">, </SPAN><SPAN style="COLOR: #0000ff">in</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">), test1)<BR>        METHOD_DEFINE_D(</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">(</SPAN><SPAN style="COLOR: #0000ff">in</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">, </SPAN><SPAN style="COLOR: #0000ff">out</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">), test2)<BR>        METHOD_DEFINE_D(</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">(</SPAN><SPAN style="COLOR: #0000ff">in</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">, inout</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">string</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">), test_func)<BR>    END_DEFINE_D ()<BR><BR>END_SERVICE_D ()</SPAN></DIV></DIV>
<P><BR>METHOD*和METHOD_DEFINE*宏的参数都有一些多余的信息，没有去掉是因为放在一起容易看到写错的地方。（这个技巧来源于前几天看的一篇BLOG，很报歉没有记下地址）<BR><BR>3、使用的问题。<BR><BR>如何才能比较方便地使用？我考虑了下面这种方式：</P>
<DIV style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 0.5pt solid; PADDING-LEFT: 5.4pt; BACKGROUND: #e6e6e6; PADDING-BOTTOM: 4px; BORDER-LEFT: windowtext 0.5pt solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: windowtext 0.5pt solid">
<DIV><SPAN style="COLOR: #000000">template </SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000"> T</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #0000ff">struct</SPAN><SPAN style="COLOR: #000000"> IProxy;<BR><BR>template </SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000"> T</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #0000ff">struct</SPAN><SPAN style="COLOR: #000000"> SOAPProxy;<BR><BR>SOAPProxy </SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #000000">TestService</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000"> service;<BR>service.connect (</SPAN><SPAN style="COLOR: #000000">5000</SPAN><SPAN style="COLOR: #000000">, </SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">localhost</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">);<BR></SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000"> a</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">0</SPAN><SPAN style="COLOR: #000000">;<BR></SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000"> </SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000">n </SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000"> </SPAN><SPAN style="COLOR: #000000">&</SPAN><SPAN style="COLOR: #000000">a;<BR>service.test1 (</SPAN><SPAN style="COLOR: #000000">3</SPAN><SPAN style="COLOR: #000000">, n);<BR>service.test1 (</SPAN><SPAN style="COLOR: #000000">3</SPAN><SPAN style="COLOR: #000000">, </SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000">n);<BR>service.test2 (</SPAN><SPAN style="COLOR: #000000">3</SPAN><SPAN style="COLOR: #000000">, n);<BR>service.test2 (</SPAN><SPAN style="COLOR: #000000">3</SPAN><SPAN style="COLOR: #000000">, </SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000">n);<BR>service.test2 (</SPAN><SPAN style="COLOR: #000000">3</SPAN><SPAN style="COLOR: #000000">, NONE);<BR></SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000"><IMG src="http://www.cppblog.com/images/dot.gif"></SPAN></DIV></DIV>
<P><BR>Method::operator ()的各个参数都将可以接受相容的类型，像上面一样，因为在TestService中我们已经定义了它要传输的值的类型。<BR><BR>a.NONE是什么？其实是为异步调用考虑的。假如指定某个OUT参数为NONE，则这个参数的值并不真正的OUT，而是保存在Method中。实际上Method中保存每个参数的值。<BR><BR>b.Method与Service如何发生关系？<BR>从TestService的定义中我们知道，Method向Service注册自己以实现自省，但它同时也会保存Service的指向。<BR>我们的Proxy实际上是一个继承模板，上面并没有把它指出来。它的定义是：</P>
<DIV style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 0.5pt solid; PADDING-LEFT: 5.4pt; BACKGROUND: #e6e6e6; PADDING-BOTTOM: 4px; BORDER-LEFT: windowtext 0.5pt solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: windowtext 0.5pt solid">
<DIV><SPAN style="COLOR: #000000">template </SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000"> T</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000"> XProxy : </SPAN><SPAN style="COLOR: #0000ff">public</SPAN><SPAN style="COLOR: #000000"> T<XPROXY><BR>{<BR>    </SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000"><IMG src="http://www.cppblog.com/images/dot.gif"></SPAN><SPAN style="COLOR: #008000"><BR></SPAN><SPAN style="COLOR: #000000">};</SPAN></DIV></DIV>
<P><BR>所以我们的TestService其实也是模板类，它将使用XProxy中定义的序列化类。XProxy将实现Service基类中序列化虚函数以及调用虚函数。<BR><BR>当一个Method调用时，它会调用Service的序列化，由于被重写了，所以调用的是XProxy中的序列化方法。这个方法会把这个Method的各in/inout参数序列化，然后执行远程调用，再把调用结果反序列化给inout/out参数。<BR><BR>4、其它想法。<BR><BR>在考虑上面的定义方式时，我也考虑了其它方式，主要是返回值处理的方法，简述如下。<BR><BR>前面我们假设了一段将被开放为远程服务的代码：</P>
<DIV style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 0.5pt solid; PADDING-LEFT: 5.4pt; BACKGROUND: #e6e6e6; PADDING-BOTTOM: 4px; BORDER-LEFT: windowtext 0.5pt solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: windowtext 0.5pt solid">
<DIV><SPAN style="COLOR: #0000ff">struct</SPAN><SPAN style="COLOR: #000000"> Test<BR>{<BR>    </SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000"> test1 (</SPAN><SPAN style="COLOR: #008000">/*</SPAN><SPAN style="COLOR: #008000">in</SPAN><SPAN style="COLOR: #008000">*/</SPAN><SPAN style="COLOR: #000000"> </SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000"> v1, </SPAN><SPAN style="COLOR: #008000">/*</SPAN><SPAN style="COLOR: #008000">in</SPAN><SPAN style="COLOR: #008000">*/</SPAN><SPAN style="COLOR: #000000"> </SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000"> v2);<BR>    </SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000"> test2 (</SPAN><SPAN style="COLOR: #008000">/*</SPAN><SPAN style="COLOR: #008000">in</SPAN><SPAN style="COLOR: #008000">*/</SPAN><SPAN style="COLOR: #000000"> </SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&</SPAN><SPAN style="COLOR: #000000"> v1, </SPAN><SPAN style="COLOR: #008000">/*</SPAN><SPAN style="COLOR: #008000">out</SPAN><SPAN style="COLOR: #008000">*/</SPAN><SPAN style="COLOR: #000000"> </SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000"> v2);<BR>};<BR><BR></SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000"> test_func (</SPAN><SPAN style="COLOR: #008000">/*</SPAN><SPAN style="COLOR: #008000">in</SPAN><SPAN style="COLOR: #008000">*/</SPAN><SPAN style="COLOR: #000000"> </SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000"> v1, </SPAN><SPAN style="COLOR: #008000">/*</SPAN><SPAN style="COLOR: #008000">inout</SPAN><SPAN style="COLOR: #008000">*/</SPAN><SPAN style="COLOR: #000000"> </SPAN><SPAN style="COLOR: #0000ff">string</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000"> v2);</SPAN></DIV></DIV>
<P><BR>在前面的做法中，我们的服务描述是放在那一组宏里面，好处是不用改这段代码，坏处就是代码定义的地方和描述不在一起，协调可能会有一些不便。<BR><BR>我也考虑了另一种做法：<BR><BR></P>
<DIV style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 0.5pt solid; PADDING-LEFT: 5.4pt; BACKGROUND: #e6e6e6; PADDING-BOTTOM: 4px; BORDER-LEFT: windowtext 0.5pt solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: windowtext 0.5pt solid">
<DIV><SPAN style="COLOR: #0000ff">struct</SPAN><SPAN style="COLOR: #000000"> Test<BR>{<BR>    idl </SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">(</SPAN><SPAN style="COLOR: #0000ff">in</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">, </SPAN><SPAN style="COLOR: #0000ff">in</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">)</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000"> test1 (</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000"> v1, </SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000"> v2);<BR>    idl </SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">(</SPAN><SPAN style="COLOR: #0000ff">in</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">, </SPAN><SPAN style="COLOR: #0000ff">out</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">)</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000"> test2 (</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&</SPAN><SPAN style="COLOR: #000000"> v1, </SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000"> v2);<BR>};<BR><BR>idl </SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">(</SPAN><SPAN style="COLOR: #0000ff">in</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">, inout</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #0000ff">string</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">) test_func </SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000"> v1, </SPAN><SPAN style="COLOR: #0000ff">string</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000"> v2);</SPAN></DIV></DIV>
<P><BR>对于实现代码，只需要修改返回值为void的函数，把return;修改为return VOID;，并且为没有写此语句的分支加上此句。<BR><BR>VOID是一个特殊类型的静态变量，专为void返回值的函数设定。<BR><BR>这种做法修改了原有的代码，不过在定义服务时可以节省一些工作：</P>
<DIV style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 0.5pt solid; PADDING-LEFT: 5.4pt; BACKGROUND: #e6e6e6; PADDING-BOTTOM: 4px; BORDER-LEFT: windowtext 0.5pt solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: windowtext 0.5pt solid">
<DIV><SPAN style="COLOR: #000000">BEGIN_SERVICE (TestService)<BR>    METHOD (test1, </SPAN><SPAN style="COLOR: #000000">&</SPAN><SPAN style="COLOR: #000000">Test::test1)<BR>    METHOD (test2, </SPAN><SPAN style="COLOR: #000000">&</SPAN><SPAN style="COLOR: #000000">Test::test2)<BR>    METHOD (test_func, test_func)<BR><BR>    BEGIN_DEFINE (TestService)<BR>        METHOD_DEFINE (test1, </SPAN><SPAN style="COLOR: #000000">&</SPAN><SPAN style="COLOR: #000000">Test::test1)<BR>        METHOD_DEFINE (test2, </SPAN><SPAN style="COLOR: #000000">&</SPAN><SPAN style="COLOR: #000000">Test::test2)<BR>        METHOD_DEFINE (test_func, test_func)<BR>    END_DEFINE ()<BR><BR>END_SERVICE ()</SPAN></DIV></DIV>
<P><BR>它所需要的函数类型，将由函数指针推导。<BR><BR>在G＋＋编译器下，可以使用typeof来获得函数指针的类型而不需要真得获得函数指针值，不过目前仅仅在G＋＋下可用。（顺便说一下，typeof已经列入c++0x）<BR><BR>最终我放弃了这个想法，毕竟它要修改现有的代码，某些情况下这是不可能的，而且typeof目前也不能跨编译器。<BR><BR>三、实现。<BR><BR>老实说我现在还没有一份完整的或半完整的实现，大部分想法还在头脑中，测试代码倒是写了不少，主要是用来测试上述想法能否实现，我想大部分情况都已经测试了，只需要有时间来把它实现出来。<BR><BR>这是我近期要做的事之一，争取月内把它做完罢。</P><img src ="http://www.cppblog.com/cpunion/aggbug/272.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cpunion/" target="_blank">qiezi</a> 2005-09-15 01:27 <a href="http://www.cppblog.com/cpunion/archive/2005/09/15/272.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>return void();天！我一直以为这是非法的！</title><link>http://www.cppblog.com/cpunion/archive/2005/09/14/267.html</link><dc:creator>qiezi</dc:creator><author>qiezi</author><pubDate>Wed, 14 Sep 2005 13:08:00 GMT</pubDate><guid>http://www.cppblog.com/cpunion/archive/2005/09/14/267.html</guid><wfw:comment>http://www.cppblog.com/cpunion/comments/267.html</wfw:comment><comments>http://www.cppblog.com/cpunion/archive/2005/09/14/267.html#Feedback</comments><slash:comments>9</slash:comments><wfw:commentRss>http://www.cppblog.com/cpunion/comments/commentRss/267.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/cpunion/services/trackbacks/267.html</trackback:ping><description><![CDATA[今天在 <A title="" href="http://blog.donews.com/jfwan" target=_blank><a title="" href="http://blog.donews.com/jfwan" target="_blank">jfwan</a></A> 的blog上看到他写的c++委托类，功能和我那个差不多，接口要完整一些。<BR><BR>我发现他并没有为void返回类型做偏特化版本，于是测试了一下：<BR>
<DIV style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 0.5pt solid; PADDING-LEFT: 5.4pt; BACKGROUND: #e6e6e6; PADDING-BOTTOM: 4px; BORDER-LEFT: windowtext 0.5pt solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: windowtext 0.5pt solid">
<DIV><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">&nbsp;test&nbsp;()<BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">return</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">();<BR>}</SPAN></DIV></DIV><BR><BR>编译一点问题都没有。<BR><BR>我一直都没想到这种用法，而且也没在其它书中看到过，上网搜索了一下，也没有发现。<BR><BR>我一定是看书太粗心了。<BR><BR><BR>补充一点，下面这个也是合法的：<BR>
<DIV style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 0.5pt solid; PADDING-LEFT: 5.4pt; BACKGROUND: #e6e6e6; PADDING-BOTTOM: 4px; BORDER-LEFT: windowtext 0.5pt solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: windowtext 0.5pt solid">
<DIV><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">&nbsp;test()&nbsp;{&nbsp;}&nbsp;<BR><BR></SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">&nbsp;test1()&nbsp;{&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">return</SPAN><SPAN style="COLOR: #000000">&nbsp;test();&nbsp;<BR>}</SPAN></DIV></DIV><img src ="http://www.cppblog.com/cpunion/aggbug/267.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cpunion/" target="_blank">qiezi</a> 2005-09-14 21:08 <a href="http://www.cppblog.com/cpunion/archive/2005/09/14/267.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转载] cpp@codingnow.com邮件列表中的一篇评论</title><link>http://www.cppblog.com/cpunion/archive/2005/09/14/263.html</link><dc:creator>qiezi</dc:creator><author>qiezi</author><pubDate>Wed, 14 Sep 2005 06:44:00 GMT</pubDate><guid>http://www.cppblog.com/cpunion/archive/2005/09/14/263.html</guid><wfw:comment>http://www.cppblog.com/cpunion/comments/263.html</wfw:comment><comments>http://www.cppblog.com/cpunion/archive/2005/09/14/263.html#Feedback</comments><slash:comments>8</slash:comments><wfw:commentRss>http://www.cppblog.com/cpunion/comments/commentRss/263.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/cpunion/services/trackbacks/263.html</trackback:ping><description><![CDATA[<P><STRONG><FONT color=#ff0000>作者要求匿名。</FONT></STRONG></P>
<P>C++当年从应用开发的王座上跌落，不是因为它有模板，而是因为它缺少更强的动态能力。基本上C++就是一种静态语言，其所谓动态性都是就编译时而言的。一旦编译完成就成为铁板一块。这个问题在单机时代还可以将就，到了网络时代就是不可容忍的问题。因此，按照毛主席的矛盾论思想说，实际上C++在90年代中期面临的主要矛盾是落后的静态执行模型与应用程序动态化之间的矛盾。但是C++当时并没有着力解决这个矛盾（到现在连个统一的ABI都没有），反而在次要矛盾（开发效率）上下功夫，花了极大的精力去完善模板设施。再加上其他固有的问题（GC, debug, pointer, 复杂性），C++就从王座上跌下来了。</P>
<P>这也可以解释，为什么Windows/MFC/COM仍然是目前C++应用的单一最大场合——因为COM是微软为C++提供的一个动态运行环境。遗憾的是，COM设计得太复杂，而且犯了一些错误（读读这篇文章<A href="http://www.relisoft.com/win32/olerant.html">http://www.relisoft.com/win32/olerant.html</A>），所以跟后来的那些什么Java、.NET相比就相形见绌了。</P>
<P>总之，C++仍然是目前制造单块系统最好的语言（效率高，抽象机制丰富，可移植性好），但用于构造整个应用，特别是网络应用，就很不合适了，至少是不经济。</P>
<P>因此，C++未来的位置只能是不断完善自己作为系统级部件语言的位置。从这个角度看：</P>
<P>1.&nbsp;&nbsp;&nbsp; Ice：用C++开发了完整的网络中间件，解决了动态性问题，并且可以跨语言。这是我认为3年以来C++开发中最令人激动的项目。</P>
<P>2.&nbsp;&nbsp;&nbsp; 陈榕的Elastos：陈榕对于这个问题的认识是很深刻的。几年以前他给我讲得其实就是这个道理，只不过我最近才想明白。他认为在构造单个部件方面，C++由于C#、VB、Java，特别是在嵌入式平台上优势明显。而主要的缺陷是C++部件的动态性能极度匮乏，这里的关键因素又是因为C++部件中的metadata匮乏。因此陈榕给C++部件添加完整的metadata，并开发运行时来支持。陈榕的思想实际上与Ice是一致的，只不过两者一个是从CORBA出来的，一个是从COM出来的，殊途同归而已。我非常认同陈榕的发展方向，唯一的担忧是，陈榕的C++部件metadata是与.NET兼容的，而目前企业应用中的主流是Java。这个矛盾应该得到解决。如果陈榕的Elastos能够同时兼容Java的metadata和.NET的metadata，我相信他会取得成功。</P>
<P>3.&nbsp;&nbsp;&nbsp; 微软的C++/CLI，这个东西被骂得很惨，其实放在大背景下考虑，它是有意义的。实际上它的出现是同样基于我上面提到的一个观点，即做零件的话，你们谁也不如C++。所以C++是有优势的，只不过要把C++作出来的零件跟其他的零件自如拼装。C++/CLI致力于在.NET体系内部解决这个问题，不能说这个想法是不对的，我认为这个技术将会得到一定程度的应用。</P>
<P>4.&nbsp;&nbsp;&nbsp; 相比之下，像ACE/MFC/Qt这类大型的框架，虽然已经非常成熟，但是未来将局限在一个比较小的领域里，局面会比较尴尬。因为它们是用来开发整个应用程序的，而未来大家不太会用C++来开发整个应用。那么用它们来开发部件如何呢？不好，因为它们开发出来的部件不能与外界交互。不过ACE还是有一定空间的，因为它的可移植性超好，可以往嵌入时平台上挤，而且在上面还有TAO和CIAO。</P>
<P>5.&nbsp;&nbsp;&nbsp; ATL怎样呢？那完全取决于COM的命运。只要COM在Windows中还处于核心的地位，ATL就还是很重要的技术。</P>
<P>6.&nbsp;&nbsp;&nbsp; Boost对于C++来说，只是一个补充性质的事件，无关乎大局。</P>
<P>7.&nbsp;&nbsp;&nbsp; 我一直坚信未来会出现高低搭配的局面，像Java/C#这样的半动不静的中级语言会逐渐“沦为”JVM和CLR上的系统语言，应用开发的任务必将由更加动态的脚本语言承担。目前的Python, Ruby和Lua都有可能。如果从我的角度讲，我希望最后胜出的是Lua，因为Python思维有些混乱，Ruby虽然很纯，但是语言设计过于复杂，只有Lua是符合我的美学观——简单而又强大，这一点跟云风意见一致。<BR></P><img src ="http://www.cppblog.com/cpunion/aggbug/263.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cpunion/" target="_blank">qiezi</a> 2005-09-14 14:44 <a href="http://www.cppblog.com/cpunion/archive/2005/09/14/263.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>