﻿<?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++博客-可冰-随笔分类-C++</title><link>http://www.cppblog.com/kb/category/53.html</link><description>冰,是沉睡着的水......</description><language>zh-cn</language><lastBuildDate>Tue, 20 May 2008 03:17:58 GMT</lastBuildDate><pubDate>Tue, 20 May 2008 03:17:58 GMT</pubDate><ttl>60</ttl><item><title>［讨论］关于注释的书写位置</title><link>http://www.cppblog.com/kb/archive/2006/04/21/6029.html</link><dc:creator>可冰</dc:creator><author>可冰</author><pubDate>Fri, 21 Apr 2006 07:20:00 GMT</pubDate><guid>http://www.cppblog.com/kb/archive/2006/04/21/6029.html</guid><wfw:comment>http://www.cppblog.com/kb/comments/6029.html</wfw:comment><comments>http://www.cppblog.com/kb/archive/2006/04/21/6029.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/kb/comments/commentRss/6029.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/kb/services/trackbacks/6029.html</trackback:ping><description><![CDATA[
		<font size="2">
				<br />        在C/C++中,变量及函数的定义一般都是在.h/.hpp文件中说明原型,而在对应的.c/.cpp文件中来进行实现.<br />        这种情况下,头文件最终是给用户使用的,以便让用户了解有哪些接口可以使用;而.c/.cpp文件是开发者使用的,以便让其它开发人员了解它的实现逻辑.因此这两个文件中肯定都是需要详细的注释的.在.h/.hpp文件中,主要说明函数的使用方法,如参数的意义,返回值的定义等.而.c/.cpp文件中,主要说明函数的实现逻辑等.<br /><br />        不知道上面的做法是否合适.请大家指正!<br />        另外,大家在实际编程过程中是如何做的?<br /><br />        事实上,我自己在实践过程中却总是偏向于把注释写到一个地方,或者注释原型,或者注释实现(前者比较多),甚至干脆两边都写一样的(但这样的话内容经常会不一样).这样的方法让我在编程过程中吃尽了苦头哇.</font>
		<br />
<img src ="http://www.cppblog.com/kb/aggbug/6029.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/kb/" target="_blank">可冰</a> 2006-04-21 15:20 <a href="http://www.cppblog.com/kb/archive/2006/04/21/6029.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C++编码规范</title><link>http://www.cppblog.com/kb/archive/2005/11/22/1240.html</link><dc:creator>可冰</dc:creator><author>可冰</author><pubDate>Tue, 22 Nov 2005 05:46:00 GMT</pubDate><guid>http://www.cppblog.com/kb/archive/2005/11/22/1240.html</guid><wfw:comment>http://www.cppblog.com/kb/comments/1240.html</wfw:comment><comments>http://www.cppblog.com/kb/archive/2005/11/22/1240.html#Feedback</comments><slash:comments>7</slash:comments><wfw:commentRss>http://www.cppblog.com/kb/comments/commentRss/1240.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/kb/services/trackbacks/1240.html</trackback:ping><description><![CDATA[<font style="font-family: Verdana; color: rgb(165, 42, 42);" size="2">//自己翻译的，本想整理一下，但一直没时间，现在就这样放上来吧，有错就批，别客气，呵呵。</font>

<h1>C++编码规范</h1>

<!--
	概述
这里	我选择了著名C++天才专家Herb Sutter和Andrei Alexandrescu的作品C++ Coding Standards: 101 Rules, Guidelines, and Best Practices中的一小节进行学习及翻译.关于这本书其实没什么好说的,它注定会成为C++程序员的圣经的.现在要做的只是学习它,并应用它.

简介
这里的是第一小节:组织与策略问题.主要阐述了以下几个方面:
 不要因小失大. (或:知道什么不需要规范化.)
 以高警告级别干净地编译
 使用自动构建系统
 使用一个版本控制系统
 在代码审阅上作投入

主要论述和分析
协调且高质量的编码标准可以改善软件质量,缩短上市时间,促进团队协作,消除花在不合理问题上的时间以及简化维护.现在,世界最受敬重的C++专家中的两位联合汇总全球C++社区丰富的集体经验,写就了一整套编码标准,每个开发者和开发团队都能够理解并应用它们作为自己的基本编码标准.
作者们实际上涉及到了C++编程的第一个方面,比如:设计和编码风格、函数、操作符、类的设计、继承、构造/析构(函数)、拷贝(函数)、赋值、命名空间、模块、模板、泛型、异常、STL容器和算法等等.每条标准都简练地描述,并配以实例.从类型定义到错误处理,这本书都呈现出C++最好的习惯,包括一些即使是C++老手也不一定知道的最近才被确定并被标准化的技术.通过此书,你将找到例如以下问题的答案:
什么值得规范化而什么不值得?
写出具有可度量的代码的最好方法是什么?
一个合理的错误处理策略的基本要素是什么?
......
不论你是独自工作或是与人合作,《C++编码标准》都将帮你以更少的争论和挫折写出更快速的更干净的代码.
当然,这里只是选择了这本书的一小节:组织与策略问题,不可能全部涵盖上述全部方面.


-->

<a name="section0">
<h2>一、组织与策略问题</h2></a>

<pre example="example">If builders built buildings the way programmers wrote programs, then the<br>first woodpecker that came along would destroy civilization.<br><div align="right">----Gerald Weinberg</div></pre>
在C和C++的主要传统中,我们认为是一种零基础的习惯.第0条是一个根本的指示,它涵盖了编码规范中我们认为是最基本的建议.<br>
在这介绍性的一节的其余部分中,我们精心选取了其中的少量问题加以阐述,这些大多与编码本身无直接关系,但却是写出可靠代码的基本工具和技术.<br>
在这一节中我们认为最有价值的是第0条不要因小失大.(或:知道什么不需要规范化.)


<a name="item0">
<h2>0. 不要因小失大. (或:知道什么不需要规范化.)</h2></a>
  <h3>摘要</h3>
  仅说必要的话:不要坚持个人品味或陈旧的习惯.

  <h3>讨论</h3>

真只是个人品味且不影响正确性或可读性的结论不属于编码标准.任何专业程序员可以很容易地读写稍微不同于他所习惯的格式的代码.<br>
在每个源文件甚至每个工程中都要用一致的格式,因为在几种不同编码风格的代码片段中跳转是很不协调的.但是不要企图在不同项目或公司中坚持一致地格式.<br>
下面是几条通用的结论,这里重要的不是去制定规则,而只是要保持与你维护的文件的风格的一致:<br>
不必明确指定要缩进多少,但要缩进以突出结构:用你喜欢的任意数量的空格缩进,但至少要在同一文件中保持一致.<br>
不必强行保持特定的行长度,但要保持行具有可读性:用你喜欢的任意长度的行长,但不要太长了.研究表明十个单词以内的宽度对眼睛跟踪是最理想的.<br>
不要过度制定命名规则,但要用一致的命名约定:仅有两点必须要做的:a)决不用"隐秘的"名称,也即以一个下划线开头或包括双下划线的名称;以及b)总是用字母全部大写的单词命名宏并且决不要考虑定义一个常用或缩写单词的宏(包括常用模板参数,比如T和U;以#define T anything定义任何东西是极其不好的做法).此外,要用一致的有意义的名称,并按照文件或模块的约定.(若你不能决定你自己的命名约定,试试这种方式：以各单词首字母大写方式命名类、函数和枚举(LikeThis);命名变量时在前者基础上小写第一个单词的首字母(likeThis);命名私有成员变量时在前者方式之后再加一个下划线(linkThis_);以全大写并用一个下划线连接各单词的方式命名宏(LINK_THIS).)<br>
不要规定注释的风格(除非有工具解析特定格式的注释生成文档),但要写有用的注释:如果可以的话以代码来代替注释(见<a href="#item16">第16条</a>).不要在注释中重复代码;它们不能被同步维护.要写解释方法和基本原理的启发性的注释.<br>
最后,不要试图坚持陈旧的规则(见<a href="#0_3">例3</a>和<a href="#0_4">例4</a>),即使它们曾在旧编码规范出现过.

  <h3>例子</h3>

<li>
<a name="0_1">例1:括号的放置.</a>下面的几种没有任何可读性上的差异.
<pre class="example">void using_k_and_r_style() {<br> // K&amp;R风格<br>}<br><br>void putting_each_brace_on_its_own_line()<br>{<br> // 括号独占一行<br>}<br><br>void or_putting_each_brace_on_its_own_line_indented()<br> {<br> // 括号独占一行并缩进<br> }<br></pre>
任何专业程序员都可以不费力地读写上面所列的任何一种风格的代码.但要保持一致性:不要随意的或以晦涩的嵌套方式放置括号,试着去遵循各文件中已有的风格.在本书中,我们的括号有意识的在排版的约束中以最好的可读性的来放置.
 

</li><li>
<a name="0_2">例2: 空格与制表符.</a>由于编辑器对制表符解释的不同,它可能被误用,或被理解成凸出,或无缩进,这种情况下一些团队合理地选择禁用制表符.其他同样有名望的团队则合理地允许制表符,而采用纪律来避免其潜在缺点.只要保持一致性:当团队成员维护其他人的代码时,如果你允许使用制表符,确保不要以代码清晰度和可读性为代价(见<a href="#item6">第6条</a>).如果你禁用制表符,允许编辑器在读入源文件时将空格转换成制表符,以便用户可以在编辑器中使用制表符;但要确保写回文件的时候将它们还原为空格.
 

</li><li>
<a name="0_3">例3: 匈牙利命名法.</a> 将类型信息合并到变量名称中的命名方式为类型不安全的语言(尤其是C)带来了一些混合的作用.但这种命名法在面向对象语言中没有好处(只有坏处),尤其在泛型编程中是根本不可能的.因此,不会有哪个C++编码规范会要求用匈牙利命名法,C++编码规范可能合理地将其排除在外.
 


</li><li>
<a name="0_4">例4: 单入口,单出口("SESE").</a> 历史上,一些编码规范要求每个函数有且仅有一个出口,也即一个返回语句.这样的要求在支持异常与析构函数的语言中是过时的,在这些语言中,函数通常都会有许多隐式的出口.取而代之的是,按照像第5条那样直接提倡更简短的函数的标准,这样会很自然地具有更容易理解代码和把握错误的特性.
 

  <h3>参考</h3>
<pre>[BoostLRG] · [Brooks95] $12 · [Constantine95] $29 · [Keffer95] p. 1 ·<br>[Kernighan99] $1.1, $1.3, $1.6-7 · [Lakos96] $1.4.1, $2.7 · [McConnell93]<br> $9, $19 · [Stroustrup94] $4.2-3 · [Stroustrup00] $4.9.3, $6.4, $7.8, $C.1<br>  · [Sutter00] $6, $20 · [SuttHysl01]<br></pre>


<a name="item1">
<h2>1. 以高警告级别干净地编译</h2></a>

  <h3>摘要</h3>

将警告铭记于心:使用你的编译器的最高警告级别.要求干净(无警告)的构建.理解全部的警告,并通过修改代码消除警告,而不是通过降低警告级别.<br>

  <h3>讨论</h3>
编译器是你的好朋友.若它由于一个特定的结构而发出一个警告,通常你的代码含有潜在的问题.<br>
成功构建应该是干净的(无警告的).如若不是这样,你将会很快养成快速浏览输出结果的习惯,进而你将错过真正的问题.(见<a href="#item2">第2条</a>)<br>
消除警告: a)理解它;然后b)更改你的代码去消除警告并让你想让它所做的事情对人和编译器都更清楚.<br>
一定要做这一步,即使一开始程序看起来正确运行了,或者即使你肯定警告是良性的.即使是良性警告也可以使后面的指出真正危险的警告变得隐晦.

  <h3>例子</h3>

</li><li>
<a name="1_1">例1: 第三方头文件.</a>你不可能去修改一个引起(或许是良性的)警告的库头文件.因此你要在你自己的头文件中包含原始头文件并仅在这个头文件的作用域内选择性的屏蔽掉这些烦人的警告,然后在你其它的项目文件中包含你的这个包装过的头文件.例如(注意这里的警告控制语法在编译器间是不同的):<br>
<pre class="example">// 文件: myproj/my_lambda.h -- 包装Boost的lambda.hpp<br>// 总是使用这个文件,而不直接使用lambda.hpp.<br>// 注意: 我们的构建现在自动检查: "grep lambda.hpp <srcfile>".<br>// Boost.Lambda产生我们所知道的无害的编译警告.<br>// 当作者修正它时我们将移除下面的#pragma语句,但是这个头文件仍将存在.<br>//<br>#pragma warning(push)     // 仅屏蔽这个头文件<br>  #pragma warning(disable:4512)<br>  #pragma warning(disable:4180)<br>  #include <boost>
#pragma warning(pop)      // 恢复原来的警告级别
</boost></srcfile></pre>
 

</li><li>
<a name="1_2">例2: "未使用过的函数参数."</a>检查以确保你真的不打算用这个函数参数(例如:它可能是占位符以便将来扩展,或是你代码中从未用到但却是必需的标准化函数签名的一部分).如若它不是必需的,只要删除这个函数参数就行了:<br>
<pre class="example">// … 不使用提示的用户自定义分配器内部 …<br><br>// 警告: "unused parameter 'localityHint'"<br>pointer allocate( size_type numObjects, const void *localityHint = 0 ) {<br>  return static_cast<pointer>( mallocShared( numObjects * sizeof(T) ) );<br>}<br><br>// 新版本: 消除警告<br>pointer allocate( size_type numObjects, const void * /* localityHint */ = 0 ) {<br>  return static_cast<pointer>( mallocShared( numObjects * sizeof(T) ));<br>}<br></pointer></pointer></pre>
 

</li><li>
<a name="1_3">例3: "变量定义了但却从未使用."</a>检查确保你真的不想引用这个变量.(一个基于栈的RAII对象经常引起这样的不合理的警告,请见<a href="#item13">第13条</a>.)如若它不是必需的,通常你可以插入一个变量自求值的表达式使编译器安静(这一求值不会对运行时速度有影响):
<pre class="example">// 警告: "变量'lock'定义了但却从未使用."<br>void Fun() {<br> Lock lock;<br><br> // …<br><br>}<br><br>// 新版本: 消除了警告<br>void Fun() {<br> Lock lock;<br> lock;<br><br> // …<br><br>}<br></pre>
 

</li><li>
<a name="1_4">例4: "可能使用了未初始化的变量."</a>那就初始化这个变量(见<a href="#item19">第19条</a>).
 


</li><li>
<a name="1_5">例5: "丢失返回语句."</a>即使你的控制流永远也不可能到达函数的末尾,编译器有时也会要求有一个返回语句(例如无限循环、异常抛出语句以及其它类型的返回语句).这也许是一件好事,因为有时你只是认为控制流不会运行到末尾.例如无default的switch语句没有修改的弹性,因些要有一个default语句执行assert( false ) (另见第<a href="#item68">68</a>和<a href="#item90">90</a>条):<br>
<pre class="example">// 警告: 丢失"return"<br>int Fun( Color c ) {<br> switch( c ) {<br> case Red:   return 2;<br> case Green: return 0;<br> case Blue:<br> case Black: return 1;<br> }<br>}<br><br>// 新版本: 消除警告<br>int Fun( Color c ) {<br> switch( c ) {<br> case Red:   return 2;<br> case Green: return 0;<br> case Blue:<br> case Black: return 1;<br> default:    assert( !"should never get here!" );   // !"string"的值为false<br>             return -1;<br> }<br>}<br></pre>
 

</li><li>
<a name="1_6">例6: "有符号/无符号不匹配."</a>有符号数与无符号数之间的比较与赋值通常不是必需的.改变参与比较的变量的类型以使满足类型匹配要求.最坏情况下,插入一个显式转换.(由于编译器为你插入这样的转换,也会警告你它所做的,所以你最好不要让它出现.)
 

  <h3>例外</h3>

有时编译器可能发出一个厌烦的甚至欺骗性的警告(比如纯粹的扰乱信息),但没有可提供的方法去消除它,而且去修改代码去消除它可能是不可实现的或是徒劳的工作.在这些罕见的情况下,作为一个团队决策,除去这个只是无聊的警告的烦人的工作是:仅使特定警告无效,并尽可能是局部性的,并写一个清晰的注释文档说明为什么这样做是必要的.

  <h3>参考</h3>
<pre>[Meyers97] $48 · [Stroustrup94] $2.6.2</pre>  


<a name="item2">
  <h2>2. 使用自动构建系统</h2></a>

  <h3>摘要</h3>
按(单个)按钮:使用一个无需用户参与的全自动("一键触发")构建系统.

  <h3>讨论</h3>
一个一键触发式构建方法是基本的.它必须进行可靠的和可重复的转换,将你的源文件转换为可交付的程序包.有很多自动构建工具可以使用,没有理由不去用它.挑选一个,使用它.<br>

我们已见过一些忽视了"一键触发"式要求的组织.一些人认为随处点几下鼠标,就可以运行一些工具来注册COM/CORBA服务,或通过手工定制的一个合理构建过程拷贝一些文件.但是你没有时间和精力可以浪费在一些机器能做得更好更快的事情上.你需要一键触发式的自动化的和可靠的构建.<br>
成功的构建应该是没有任何警告的(见第1条).理想化的构建不产生扰乱信息,而仅是一个日志消息:"构建成功完成."<br>
有两个构建模式:增量构建和完全构建.增量构建仅重建自上自增量构建或完全构建以来被修改过的文件.推论:两个连续的增量构建中的后者应该没有任何输出文件;如果有的话,你可能有一个依赖环(见第22条),或者你的构建系统执行了不必要的操作(例如生成不合理的临时文件而只是丢弃它们).<br>
一个工程可以有不同形式的完全构建.考虑用一系列本质的特征确定你的构建的参数;很可能候选者就是目标式体系结构、调试和发布、或更广(基本文件和全部文件和完全安装).一个构建设置可以创建一个产品的基本的可执行文件和库,另一个可能也创建一些辅助文件,一个完全充实的构建也可能创建一个包含你所有文件、可重发布的第三方库和安装代码的安装程序.<br>
随着工程的进行,没有自动构建的花费也在增长.如果你一开始没有用,你将浪费很多时间和资源.更糟糕的是,随着自动构建成为无法抵抗的需求,你将会有比项目一开始更多的压力.<br>
大项目可能有一个"构建师/主管",他的工作就是照料构建系统.

  <h3>参考</h3>
<pre>[Brooks95] $13, $19 · [Dewhurst03] $1 · [GnuMake] · [Stroustrup00] $9.1</pre>


<a name="item3">
  <h2>3. 使用一个版本控制系统</h2></a>

  <h3>摘要</h3>
好记性比不上烂笔头:使用一个版本控制系统(VCS).决不要让检出的文件保留很长时间.一旦你的更新的单元通过测试就尽快检入.确保检入的代码不会破坏整个构建.

  <h3>讨论</h3>
几乎所有不平凡的工程都需要一个以上的开发者和/或超过一周的工作量.在这样的工程中,你将需要比较同一文件的历史版本以确定变化是什么时候(和/或被谁)引入的.你也将需要控制和管理源代码的变化.<br>
当有多个开发者时,几个开发者很可能会在同一时间对同一文件的不同部分进行并行地更改.你需要工具以自动进行文件的检出和恢复,以及在某些时候对并发编辑的合并.VCS自动操作和控制检出,恢复以及合并.VCS比手工做的更快更准确.而且你不用花时间每天的去摆弄那些重复性的工作,你有软件要写.<br>
不要破坏构建.在VCS中的代码必须总是可以成功构建的.<br>

存在很多的版本控制系统可供选择,没有理由不去用它.最便宜和流行的是cvs(见参考).它是一个灵活的工具,具胡TCP/IP访问特性,可选择性的提高安全性(通过用安全外壳SSH作为后端),卓越的脚本管理,甚至有图形接口.许多其它VCS也将cvs作为标准去效仿,或基于它构建新的功能.

  <h3>例外</h3>
从始至终只花一周左右时间的一个程序员的项目或许可以不需要VCS而生存吧.

  <h3>参考</h3>
<pre>[BetterSCM] · [Brooks95] $11, $13 · [CVS]</pre>


<a name="item4">
  <h2>4. 在代码审阅上作投入</h2></a>

  <h3>摘要</h3>

代码审阅:更多双眼睛将会带来更好的质量.展示你的代码,并阅读他人的.你们都将相互学习或受益.

  <h3>讨论</h3>
一个良好的代码审阅过程在许多方面都对你的团队有好处.它可以:
<pre><li>有益的平等的压力可以增加代码质量.<br></li><li>可以找到bugs、移植性不好的代码以及潜在的度量问题. <br></li><li>通过思想的互补培养形成的设计和实现. <br></li><li>带动新成员和初级者迅速提升能力. <br></li><li>在团队中形成共同价值和团队意识. <br></li><li>增加精英、信心、动机和专业自豪心. <br></li></pre>
许多开发商既不对代码质量和团队质量进行奖赏,也不投入时间和金钱鼓励他们.希望我们从现在起几年都不会食言,但我们感觉到这种趋势正在慢慢改变,部分原因是由于对安全软件的需求的增长.代码审阅正有助于这种趋势,另外也是一个极好的(和免费的)内部训练方法.<br>
即使你的雇主还不支持代码审阅方法,你也要增加管理知识(提示:要开始,给他们看这本书)以及无论如何要尽你最大努力去安排时间并引导审阅的进行.这时间是值得花的.<br>
将代码审阅作为你的软件开发周期的一项常规程序.如果你和你的队友赞同基于激励(也可能是挫折)的奖惩制度,就会好得多.<br>

不要做得太形式化了,写一封简单的邮件就足够将代码审阅做得很好了.这会使你更容易跟踪自己的进程以及避免重复.<br>
当审阅他人的代码时,你可能想在旁边保留一个供参考的清单.窃以为一个好的清单可能正是你正在读的这本书的目录表.满意吧!<br>
摘要:我们知道我们在给"唱诗班"布道,但是不得不说.你们的自负或自我主义也许讨厌代码审阅,但你们中的少量天才程序员喜欢它,因为它会有成效并使代码更好,使程序更强健.

  <h3>参考</h3>
<pre>[Constantine95] $10, $22, $33 · [McConnell93] $24 · [MozillaCRFAQ]</pre>



<!--
结论和观点总结
它对一些最基本的准则作了一些阐述,尤其是第0条,它使很多过度追究编码规范的人从这样无聊的工作中摆脱出来了,它让人记住这样一个观点:编码规范不是最终目标,它只是为了方便代码的编写和维护,不要舍本逐末!
参考资料
《C++ Coding Standards: 101 Rules, Guidelines, and Best Practices》
 -->


</li><img src ="http://www.cppblog.com/kb/aggbug/1240.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/kb/" target="_blank">可冰</a> 2005-11-22 13:46 <a href="http://www.cppblog.com/kb/archive/2005/11/22/1240.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>评价一下UTF-8与UNICODE相互转换的代码</title><link>http://www.cppblog.com/kb/archive/2005/09/29/491.html</link><dc:creator>可冰</dc:creator><author>可冰</author><pubDate>Thu, 29 Sep 2005 12:34:00 GMT</pubDate><guid>http://www.cppblog.com/kb/archive/2005/09/29/491.html</guid><wfw:comment>http://www.cppblog.com/kb/comments/491.html</wfw:comment><comments>http://www.cppblog.com/kb/archive/2005/09/29/491.html#Feedback</comments><slash:comments>8</slash:comments><wfw:commentRss>http://www.cppblog.com/kb/comments/commentRss/491.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/kb/services/trackbacks/491.html</trackback:ping><description><![CDATA[<font color="#000000" face="Verdana" size="2">上周,我花了很多心思使用模板写了一个UTF-8与UNICODE相互转换的功能(见文件</font><a href="http://www.cnblogs.com/Files/kb/Code.rar"><font color="#000080" face="Verdana" size="2">code.rar</font></a><font color="#000000" face="Verdana" size="2">),刚开始感觉还可以,但这几天慢慢的觉得,为什么不直接提供两个函数呢,这样不是简单方便吗?我这样的设计又能带来额外的什么好处呢?刚开始我是想提供比较方便好用以及容易扩展与维护的代码,但现在感觉到与直接提供C式的函数并没有多少额外的好处.或许这样的简单功能根本就用不着这样复杂的代码吧.正如Eric Raymond对C++的评价一样,它"使程序员倾向于写复杂的代码".<br>我想大家看看我的代码,给我一点意见和建议.</font><img src ="http://www.cppblog.com/kb/aggbug/491.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/kb/" target="_blank">可冰</a> 2005-09-29 20:34 <a href="http://www.cppblog.com/kb/archive/2005/09/29/491.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>关于模板的类型参数</title><link>http://www.cppblog.com/kb/archive/2005/09/29/490.html</link><dc:creator>可冰</dc:creator><author>可冰</author><pubDate>Thu, 29 Sep 2005 11:51:00 GMT</pubDate><guid>http://www.cppblog.com/kb/archive/2005/09/29/490.html</guid><wfw:comment>http://www.cppblog.com/kb/comments/490.html</wfw:comment><comments>http://www.cppblog.com/kb/archive/2005/09/29/490.html#Feedback</comments><slash:comments>9</slash:comments><wfw:commentRss>http://www.cppblog.com/kb/comments/commentRss/490.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/kb/services/trackbacks/490.html</trackback:ping><description><![CDATA[<FONT face=Verdana size=2>看了cpunion写的IDL的代码,我知道了这样的用法:<BR>在模板参数中,类型参数可以这样构造:<BR>        template_class< type( type1, type2, ... ) > a_class;<BR>比如,可以void( void ), void(), void( int ), 也可以int( void ), string( int )等等,编译器是将它们当作不同的类型的来处理的.对此,我写了一些代码作了一下测试(见文末).但我也仅仅是有一个感性的认识而已,对于其为什么可以这样(因为从未见哪本书上介绍过这样的用法),我一点也不知道.<BR>希望大家帮我释疑,也希望cpunion来帮我一下,谢谢!<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"><IMG src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align=top><SPAN style="COLOR: #000000"><BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align=top>#include </SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #000000">iostream</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000"><BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align=top><BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align=top>typedef </SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">(</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000">fun)(</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">);<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align=top><BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align=top></SPAN><SPAN style="COLOR: #0000ff">using</SPAN><SPAN style="COLOR: #000000"> </SPAN><SPAN style="COLOR: #0000ff">namespace</SPAN><SPAN style="COLOR: #000000"> std;<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align=top><BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align=top>template</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #000000"> <FONT color=#0000ff>typename</FONT> T </SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000"><BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align=top></SPAN><SPAN style="COLOR: #0000ff">struct</SPAN><SPAN style="COLOR: #000000"> Base<BR><IMG id=Codehighlighter1_105_214_Open_Image onclick="this.style.display='none'; Codehighlighter1_105_214_Open_Text.style.display='none'; Codehighlighter1_105_214_Closed_Image.style.display='inline'; Codehighlighter1_105_214_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align=top><IMG id=Codehighlighter1_105_214_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_105_214_Closed_Text.style.display='none'; Codehighlighter1_105_214_Open_Image.style.display='inline'; Codehighlighter1_105_214_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align=top></SPAN><SPAN id=Codehighlighter1_105_214_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><IMG src="http://www.cppblog.com/images/dot.gif"></SPAN><SPAN id=Codehighlighter1_105_214_Open_Text><SPAN style="COLOR: #000000">{<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top>    </SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000"> test()<BR><IMG id=Codehighlighter1_121_212_Open_Image onclick="this.style.display='none'; Codehighlighter1_121_212_Open_Text.style.display='none'; Codehighlighter1_121_212_Closed_Image.style.display='inline'; Codehighlighter1_121_212_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><IMG id=Codehighlighter1_121_212_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_121_212_Closed_Text.style.display='none'; Codehighlighter1_121_212_Open_Image.style.display='inline'; Codehighlighter1_121_212_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedSubBlock.gif" align=top>    </SPAN><SPAN id=Codehighlighter1_121_212_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><IMG src="http://www.cppblog.com/images/dot.gif"></SPAN><SPAN id=Codehighlighter1_121_212_Open_Text><SPAN style="COLOR: #000000">{<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top>        cout </SPAN><SPAN style="COLOR: #000000"><<</SPAN><SPAN style="COLOR: #000000"> </SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">Base<T></SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000"> </SPAN><SPAN style="COLOR: #000000"><<</SPAN><SPAN style="COLOR: #000000"> </SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">\t=\t</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">;<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top>        cout </SPAN><SPAN style="COLOR: #000000"><<</SPAN><SPAN style="COLOR: #000000"> </SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">Base<</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000"> </SPAN><SPAN style="COLOR: #000000"><<</SPAN><SPAN style="COLOR: #000000"> <FONT color=#0000ff>typeid</FONT>(T).name() </SPAN><SPAN style="COLOR: #000000"><<</SPAN><SPAN style="COLOR: #000000"> </SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000"> </SPAN><SPAN style="COLOR: #000000"><<</SPAN><SPAN style="COLOR: #000000"> endl;<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>    }</SPAN></SPAN><SPAN style="COLOR: #000000"><BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>}</SPAN></SPAN><SPAN style="COLOR: #000000">;<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align=top><BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align=top>template</SPAN><SPAN style="COLOR: #000000"><></SPAN><SPAN style="COLOR: #000000"><BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align=top></SPAN><SPAN style="COLOR: #0000ff">struct</SPAN><SPAN style="COLOR: #000000"> Base </SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #000000"> </SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000"> </SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000"><BR><IMG id=Codehighlighter1_250_303_Open_Image onclick="this.style.display='none'; Codehighlighter1_250_303_Open_Text.style.display='none'; Codehighlighter1_250_303_Closed_Image.style.display='inline'; Codehighlighter1_250_303_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align=top><IMG id=Codehighlighter1_250_303_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_250_303_Closed_Text.style.display='none'; Codehighlighter1_250_303_Open_Image.style.display='inline'; Codehighlighter1_250_303_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align=top></SPAN><SPAN id=Codehighlighter1_250_303_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><IMG src="http://www.cppblog.com/images/dot.gif"></SPAN><SPAN id=Codehighlighter1_250_303_Open_Text><SPAN style="COLOR: #000000">{<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top>    </SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000"> test()<BR><IMG id=Codehighlighter1_266_301_Open_Image onclick="this.style.display='none'; Codehighlighter1_266_301_Open_Text.style.display='none'; Codehighlighter1_266_301_Closed_Image.style.display='inline'; Codehighlighter1_266_301_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><IMG id=Codehighlighter1_266_301_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_266_301_Closed_Text.style.display='none'; Codehighlighter1_266_301_Open_Image.style.display='inline'; Codehighlighter1_266_301_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedSubBlock.gif" align=top>    </SPAN><SPAN id=Codehighlighter1_266_301_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><IMG src="http://www.cppblog.com/images/dot.gif"></SPAN><SPAN id=Codehighlighter1_266_301_Open_Text><SPAN style="COLOR: #000000">{<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top>        cout </SPAN><SPAN style="COLOR: #000000"><<</SPAN><SPAN style="COLOR: #000000"> </SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">Base<void></SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000"> </SPAN><SPAN style="COLOR: #000000"><<</SPAN><SPAN style="COLOR: #000000"> endl;<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>    }</SPAN></SPAN><SPAN style="COLOR: #000000"><BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>}</SPAN></SPAN><SPAN style="COLOR: #000000">;<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align=top><BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align=top>template</SPAN><SPAN style="COLOR: #000000"><></SPAN><SPAN style="COLOR: #000000"><BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align=top></SPAN><SPAN style="COLOR: #0000ff">struct</SPAN><SPAN style="COLOR: #000000"> Base </SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #000000"> </SPAN><SPAN style="COLOR: #0000ff">void</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"><BR><IMG id=Codehighlighter1_346_404_Open_Image onclick="this.style.display='none'; Codehighlighter1_346_404_Open_Text.style.display='none'; Codehighlighter1_346_404_Closed_Image.style.display='inline'; Codehighlighter1_346_404_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align=top><IMG id=Codehighlighter1_346_404_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_346_404_Closed_Text.style.display='none'; Codehighlighter1_346_404_Open_Image.style.display='inline'; Codehighlighter1_346_404_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align=top></SPAN><SPAN id=Codehighlighter1_346_404_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><IMG src="http://www.cppblog.com/images/dot.gif"></SPAN><SPAN id=Codehighlighter1_346_404_Open_Text><SPAN style="COLOR: #000000">{<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top>    </SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000"> test()<BR><IMG id=Codehighlighter1_362_402_Open_Image onclick="this.style.display='none'; Codehighlighter1_362_402_Open_Text.style.display='none'; Codehighlighter1_362_402_Closed_Image.style.display='inline'; Codehighlighter1_362_402_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><IMG id=Codehighlighter1_362_402_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_362_402_Closed_Text.style.display='none'; Codehighlighter1_362_402_Open_Image.style.display='inline'; Codehighlighter1_362_402_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedSubBlock.gif" align=top>    </SPAN><SPAN id=Codehighlighter1_362_402_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><IMG src="http://www.cppblog.com/images/dot.gif"></SPAN><SPAN id=Codehighlighter1_362_402_Open_Text><SPAN style="COLOR: #000000">{<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top>        cout </SPAN><SPAN style="COLOR: #000000"><<</SPAN><SPAN style="COLOR: #000000"> </SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">Base<void(int)></SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000"> </SPAN><SPAN style="COLOR: #000000"><<</SPAN><SPAN style="COLOR: #000000"> endl;<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>    }</SPAN></SPAN><SPAN style="COLOR: #000000"><BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>}</SPAN></SPAN><SPAN style="COLOR: #000000">;<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align=top><BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align=top>template</SPAN><SPAN style="COLOR: #000000"><></SPAN><SPAN style="COLOR: #000000"><BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align=top></SPAN><SPAN style="COLOR: #0000ff">struct</SPAN><SPAN style="COLOR: #000000"> Base </SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #000000"> fun </SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000"><BR><IMG id=Codehighlighter1_439_491_Open_Image onclick="this.style.display='none'; Codehighlighter1_439_491_Open_Text.style.display='none'; Codehighlighter1_439_491_Closed_Image.style.display='inline'; Codehighlighter1_439_491_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align=top><IMG id=Codehighlighter1_439_491_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_439_491_Closed_Text.style.display='none'; Codehighlighter1_439_491_Open_Image.style.display='inline'; Codehighlighter1_439_491_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align=top></SPAN><SPAN id=Codehighlighter1_439_491_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><IMG src="http://www.cppblog.com/images/dot.gif"></SPAN><SPAN id=Codehighlighter1_439_491_Open_Text><SPAN style="COLOR: #000000">{<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top>    </SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000"> test()<BR><IMG id=Codehighlighter1_455_489_Open_Image onclick="this.style.display='none'; Codehighlighter1_455_489_Open_Text.style.display='none'; Codehighlighter1_455_489_Closed_Image.style.display='inline'; Codehighlighter1_455_489_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><IMG id=Codehighlighter1_455_489_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_455_489_Closed_Text.style.display='none'; Codehighlighter1_455_489_Open_Image.style.display='inline'; Codehighlighter1_455_489_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedSubBlock.gif" align=top>    </SPAN><SPAN id=Codehighlighter1_455_489_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><IMG src="http://www.cppblog.com/images/dot.gif"></SPAN><SPAN id=Codehighlighter1_455_489_Open_Text><SPAN style="COLOR: #000000">{<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top>        cout </SPAN><SPAN style="COLOR: #000000"><<</SPAN><SPAN style="COLOR: #000000"> </SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">Base<fun></SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000"> </SPAN><SPAN style="COLOR: #000000"><<</SPAN><SPAN style="COLOR: #000000"> endl;<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>    }</SPAN></SPAN><SPAN style="COLOR: #000000"><BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>}</SPAN></SPAN><SPAN style="COLOR: #000000">;<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align=top><BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align=top>template</SPAN><SPAN style="COLOR: #000000"><></SPAN><SPAN style="COLOR: #000000"><BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align=top></SPAN><SPAN style="COLOR: #0000ff">struct</SPAN><SPAN style="COLOR: #000000"> Base </SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #000000"> </SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">( </SPAN><SPAN style="COLOR: #0000ff">string</SPAN><SPAN style="COLOR: #000000">, </SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">, </SPAN><SPAN style="COLOR: #0000ff">char</SPAN><SPAN style="COLOR: #000000"> ) </SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000"><BR><IMG id=Codehighlighter1_547_616_Open_Image onclick="this.style.display='none'; Codehighlighter1_547_616_Open_Text.style.display='none'; Codehighlighter1_547_616_Closed_Image.style.display='inline'; Codehighlighter1_547_616_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align=top><IMG id=Codehighlighter1_547_616_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_547_616_Closed_Text.style.display='none'; Codehighlighter1_547_616_Open_Image.style.display='inline'; Codehighlighter1_547_616_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align=top></SPAN><SPAN id=Codehighlighter1_547_616_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><IMG src="http://www.cppblog.com/images/dot.gif"></SPAN><SPAN id=Codehighlighter1_547_616_Open_Text><SPAN style="COLOR: #000000">{<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top>    </SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000"> test()<BR><IMG id=Codehighlighter1_563_614_Open_Image onclick="this.style.display='none'; Codehighlighter1_563_614_Open_Text.style.display='none'; Codehighlighter1_563_614_Closed_Image.style.display='inline'; Codehighlighter1_563_614_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><IMG id=Codehighlighter1_563_614_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_563_614_Closed_Text.style.display='none'; Codehighlighter1_563_614_Open_Image.style.display='inline'; Codehighlighter1_563_614_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedSubBlock.gif" align=top>    </SPAN><SPAN id=Codehighlighter1_563_614_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><IMG src="http://www.cppblog.com/images/dot.gif"></SPAN><SPAN id=Codehighlighter1_563_614_Open_Text><SPAN style="COLOR: #000000">{<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top>        cout </SPAN><SPAN style="COLOR: #000000"><<</SPAN><SPAN style="COLOR: #000000"> </SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">Base<int(string,int,char)></SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000"> </SPAN><SPAN style="COLOR: #000000"><<</SPAN><SPAN style="COLOR: #000000"> endl;<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>    }</SPAN></SPAN><SPAN style="COLOR: #000000"><BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>}</SPAN></SPAN><SPAN style="COLOR: #000000">;<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align=top><BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align=top></SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000"> main(</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000"> argc, </SPAN><SPAN style="COLOR: #0000ff">char</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000"> argv[])<BR><IMG id=Codehighlighter1_653_943_Open_Image onclick="this.style.display='none'; Codehighlighter1_653_943_Open_Text.style.display='none'; Codehighlighter1_653_943_Closed_Image.style.display='inline'; Codehighlighter1_653_943_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align=top><IMG id=Codehighlighter1_653_943_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_653_943_Closed_Text.style.display='none'; Codehighlighter1_653_943_Open_Image.style.display='inline'; Codehighlighter1_653_943_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align=top></SPAN><SPAN id=Codehighlighter1_653_943_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><IMG src="http://www.cppblog.com/images/dot.gif"></SPAN><SPAN id=Codehighlighter1_653_943_Open_Text><SPAN style="COLOR: #000000">{<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top>    Base</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #000000"> </SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000"> </SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000"> b_void;<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top>    Base</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #000000"> </SPAN><SPAN style="COLOR: #0000ff">void</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"> b_void_int;<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top>    b_void.test();<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top>    b_void_int.test();<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top><BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top>    Base</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #000000"> </SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">( </SPAN><SPAN style="COLOR: #0000ff">string</SPAN><SPAN style="COLOR: #000000">, </SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">, </SPAN><SPAN style="COLOR: #0000ff">char</SPAN><SPAN style="COLOR: #000000"> ) </SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000"> b_int;<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top>    Base</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #000000"> fun </SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000"> b_fun;<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top>    b_int.test();<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top>    b_fun.test();<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top><BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top><BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top>    Base</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #000000"> Base</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #000000"> </SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000"> </SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000"> ( Base </SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #000000"> </SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000"> ( </SPAN><SPAN style="COLOR: #0000ff">string</SPAN><SPAN style="COLOR: #000000">, </SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">, </SPAN><SPAN style="COLOR: #0000ff">char</SPAN><SPAN style="COLOR: #000000"> ) </SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000"> ) </SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000"> b_complex;<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top>    b_complex.test();<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top><BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top>    </SPAN><SPAN style="COLOR: #0000ff">return</SPAN><SPAN style="COLOR: #000000"> </SPAN><SPAN style="COLOR: #000000">0</SPAN><SPAN style="COLOR: #000000">;<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>}</SPAN></SPAN><SPAN style="COLOR: #000000"><BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align=top><BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align=top></SPAN></DIV></FONT><img src ="http://www.cppblog.com/kb/aggbug/490.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/kb/" target="_blank">可冰</a> 2005-09-29 19:51 <a href="http://www.cppblog.com/kb/archive/2005/09/29/490.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>error C2899: 不能在模板声明之外使用类型名称 ?!!</title><link>http://www.cppblog.com/kb/archive/2005/09/24/414.html</link><dc:creator>可冰</dc:creator><author>可冰</author><pubDate>Sat, 24 Sep 2005 07:49:00 GMT</pubDate><guid>http://www.cppblog.com/kb/archive/2005/09/24/414.html</guid><wfw:comment>http://www.cppblog.com/kb/comments/414.html</wfw:comment><comments>http://www.cppblog.com/kb/archive/2005/09/24/414.html#Feedback</comments><slash:comments>5</slash:comments><wfw:commentRss>http://www.cppblog.com/kb/comments/commentRss/414.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/kb/services/trackbacks/414.html</trackback:ping><description><![CDATA[<FONT face=Verdana size=2>前天碰到一个问题,当时想着挺纳闷的,不知道是什么原因.对"不能在模板声明之外使用类型名称"这样的提示你会想到是什么?我在无意中按F1键看到MSDN中的描述才明白是typename关键字用错了,是看它的英文描述才知道的:"<STRONG>typename cannot be used outside a template declaration</STRONG>".真想不到typename会翻译为类型名称.看来,以后有莫名其妙的错误还是得看英文的帮助文档啊,不过最好一开始就有英文版的VS.NET.<BR>以下是具体的描述:</FONT><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"><FONT size=2><FONT face=Verdana><IMG src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align=top><SPAN style="COLOR: #0000ff">namespace</SPAN></FONT></FONT><FONT size=2><FONT face=Verdana><SPAN style="COLOR: #000000"> code<BR><IMG id=Codehighlighter1_15_664_Open_Image onclick="this.style.display='none'; Codehighlighter1_15_664_Open_Text.style.display='none'; Codehighlighter1_15_664_Closed_Image.style.display='inline'; Codehighlighter1_15_664_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align=top><IMG id=Codehighlighter1_15_664_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_15_664_Closed_Text.style.display='none'; Codehighlighter1_15_664_Open_Image.style.display='inline'; Codehighlighter1_15_664_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align=top></SPAN><SPAN id=Codehighlighter1_15_664_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><IMG src="http://www.cppblog.com/images/dot.gif"></SPAN></FONT></FONT><SPAN id=Codehighlighter1_15_664_Open_Text><FONT size=2><FONT face=Verdana><SPAN style="COLOR: #000000">{<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top><BR><IMG id=Codehighlighter1_32_49_Open_Image onclick="this.style.display='none'; Codehighlighter1_32_49_Open_Text.style.display='none'; Codehighlighter1_32_49_Closed_Image.style.display='inline'; Codehighlighter1_32_49_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><IMG id=Codehighlighter1_32_49_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_32_49_Closed_Text.style.display='none'; Codehighlighter1_32_49_Open_Image.style.display='inline'; Codehighlighter1_32_49_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedSubBlock.gif" align=top></SPAN><SPAN style="COLOR: #0000ff">enum</SPAN><SPAN style="COLOR: #000000"> CodeType </SPAN><SPAN id=Codehighlighter1_32_49_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><IMG src="http://www.cppblog.com/images/dot.gif"></SPAN><SPAN id=Codehighlighter1_32_49_Open_Text><SPAN style="COLOR: #000000">{ UTF_8, UNICODE }</SPAN></SPAN></FONT></FONT><FONT size=2><FONT face=Verdana><SPAN style="COLOR: #000000">;<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top><BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top>template</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #000000"> CodeType srcT, CodeType desT </SPAN><SPAN style="COLOR: #000000">></SPAN></FONT></FONT><SPAN style="COLOR: #000000"><BR><FONT face=Verdana size=2><IMG id=Codehighlighter1_112_113_Open_Image onclick="this.style.display='none'; Codehighlighter1_112_113_Open_Text.style.display='none'; Codehighlighter1_112_113_Closed_Image.style.display='inline'; Codehighlighter1_112_113_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><IMG id=Codehighlighter1_112_113_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_112_113_Closed_Text.style.display='none'; Codehighlighter1_112_113_Open_Image.style.display='inline'; Codehighlighter1_112_113_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedSubBlock.gif" align=top></FONT></SPAN><FONT size=2><FONT face=Verdana><SPAN style="COLOR: #0000ff">struct</SPAN><SPAN style="COLOR: #000000"> ConvertType</SPAN><SPAN id=Codehighlighter1_112_113_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><IMG src="http://www.cppblog.com/images/dot.gif"></SPAN><SPAN id=Codehighlighter1_112_113_Open_Text><SPAN style="COLOR: #000000">{}</SPAN></SPAN></FONT></FONT><FONT size=2><FONT face=Verdana><SPAN style="COLOR: #000000">;<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top><BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top>template</SPAN><SPAN style="COLOR: #000000"><></SPAN></FONT></FONT><SPAN style="COLOR: #000000"><BR><FONT face=Verdana size=2><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top></FONT></SPAN><FONT size=2><FONT face=Verdana><SPAN style="COLOR: #0000ff">struct</SPAN><SPAN style="COLOR: #000000"> ConvertType </SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #000000"> UTF_8, UNICODE </SPAN><SPAN style="COLOR: #000000">></SPAN></FONT></FONT><SPAN style="COLOR: #000000"><BR><FONT face=Verdana size=2><IMG id=Codehighlighter1_166_217_Open_Image onclick="this.style.display='none'; Codehighlighter1_166_217_Open_Text.style.display='none'; Codehighlighter1_166_217_Closed_Image.style.display='inline'; Codehighlighter1_166_217_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><IMG id=Codehighlighter1_166_217_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_166_217_Closed_Text.style.display='none'; Codehighlighter1_166_217_Open_Image.style.display='inline'; Codehighlighter1_166_217_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedSubBlock.gif" align=top></FONT></SPAN><SPAN id=Codehighlighter1_166_217_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><FONT face=Verdana size=2><IMG src="http://www.cppblog.com/images/dot.gif"></FONT></SPAN><SPAN id=Codehighlighter1_166_217_Open_Text><FONT size=2><FONT face=Verdana><SPAN style="COLOR: #000000">{<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top>    typedef </SPAN><SPAN style="COLOR: #0000ff">char</SPAN></FONT></FONT><SPAN style="COLOR: #000000"><FONT face=Verdana size=2> srcType;<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top>    typedef wchar_t desType;<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>}</FONT></SPAN></SPAN><FONT size=2><FONT face=Verdana><SPAN style="COLOR: #000000">;<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top><BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top>template</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #000000"> CodeType srcT, CodeType desT </SPAN><SPAN style="COLOR: #000000">></SPAN></FONT></FONT><SPAN style="COLOR: #000000"><BR><FONT face=Verdana size=2><IMG id=Codehighlighter1_277_278_Open_Image onclick="this.style.display='none'; Codehighlighter1_277_278_Open_Text.style.display='none'; Codehighlighter1_277_278_Closed_Image.style.display='inline'; Codehighlighter1_277_278_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><IMG id=Codehighlighter1_277_278_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_277_278_Closed_Text.style.display='none'; Codehighlighter1_277_278_Open_Image.style.display='inline'; Codehighlighter1_277_278_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedSubBlock.gif" align=top></FONT></SPAN><FONT size=2><FONT face=Verdana><SPAN style="COLOR: #0000ff">struct</SPAN><SPAN style="COLOR: #000000"> Convert </SPAN><SPAN id=Codehighlighter1_277_278_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><IMG src="http://www.cppblog.com/images/dot.gif"></SPAN><SPAN id=Codehighlighter1_277_278_Open_Text><SPAN style="COLOR: #000000">{}</SPAN></SPAN></FONT></FONT><FONT size=2><FONT face=Verdana><SPAN style="COLOR: #000000">;<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top><BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top>template</SPAN><SPAN style="COLOR: #000000"><></SPAN></FONT></FONT><SPAN style="COLOR: #000000"><BR><FONT face=Verdana size=2><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top></FONT></SPAN><FONT size=2><FONT face=Verdana><SPAN style="COLOR: #0000ff">struct</SPAN><SPAN style="COLOR: #000000"> Convert</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #000000"> UTF_8, UNICODE </SPAN><SPAN style="COLOR: #000000">></SPAN></FONT></FONT><SPAN style="COLOR: #000000"><BR><FONT face=Verdana size=2><IMG id=Codehighlighter1_326_660_Open_Image onclick="this.style.display='none'; Codehighlighter1_326_660_Open_Text.style.display='none'; Codehighlighter1_326_660_Closed_Image.style.display='inline'; Codehighlighter1_326_660_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><IMG id=Codehighlighter1_326_660_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_326_660_Closed_Text.style.display='none'; Codehighlighter1_326_660_Open_Image.style.display='inline'; Codehighlighter1_326_660_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedSubBlock.gif" align=top></FONT></SPAN><SPAN id=Codehighlighter1_326_660_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><FONT face=Verdana size=2><IMG src="http://www.cppblog.com/images/dot.gif"></FONT></SPAN><SPAN id=Codehighlighter1_326_660_Open_Text><FONT size=2><FONT face=Verdana><SPAN style="COLOR: #000000">{<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top>    </SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000">error C2899: 不能在模板声明之外使用类型名称</SPAN></FONT></FONT><SPAN style="COLOR: #008000"><BR><FONT face=Verdana size=2><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top></FONT></SPAN><FONT size=2><FONT face=Verdana><SPAN style="COLOR: #000000">    typedef typename ConvertType</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #000000"> UTF_8, UNICODE </SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">::srcType srcType;    </SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000">!</SPAN></FONT></FONT><SPAN style="COLOR: #008000"><BR><FONT face=Verdana size=2><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top></FONT></SPAN><FONT size=2><FONT face=Verdana><SPAN style="COLOR: #000000">    typedef typename ConvertType</SPAN><SPAN style="COLOR: #000000"><</SPAN><SPAN style="COLOR: #000000"> UTF_8, UNICODE </SPAN><SPAN style="COLOR: #000000">></SPAN><SPAN style="COLOR: #000000">::desType desType;    </SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000">!</SPAN></FONT></FONT><SPAN style="COLOR: #008000"><BR><FONT face=Verdana size=2><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top></FONT></SPAN><SPAN style="COLOR: #000000"><FONT face=Verdana size=2><IMG src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>}</FONT></SPAN></SPAN><SPAN style="COLOR: #000000"><FONT face=Verdana size=2>;<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top><BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>}</FONT></SPAN></SPAN><FONT size=2><FONT face=Verdana><SPAN style="COLOR: #000000"> </SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000">namespace code</SPAN></FONT></FONT><SPAN style="COLOR: #008000"><BR><FONT face=Verdana size=2><IMG src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align=top></FONT></SPAN><SPAN style="COLOR: #000000"><BR><FONT face=Verdana size=2><IMG src="http://www.cppblog.com/images/OutliningIndicators/None.gif" align=top><BR><IMG id=Codehighlighter1_685_1207_Open_Image onclick="this.style.display='none'; Codehighlighter1_685_1207_Open_Text.style.display='none'; Codehighlighter1_685_1207_Closed_Image.style.display='inline'; Codehighlighter1_685_1207_Closed_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align=top><IMG id=Codehighlighter1_685_1207_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_685_1207_Closed_Text.style.display='none'; Codehighlighter1_685_1207_Open_Image.style.display='inline'; Codehighlighter1_685_1207_Open_Text.style.display='inline';" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif" align=top></FONT></SPAN><SPAN id=Codehighlighter1_685_1207_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><FONT face=Verdana size=2>/**/</FONT></SPAN><SPAN id=Codehighlighter1_685_1207_Open_Text><SPAN style="COLOR: #008000"><FONT face=Verdana size=2>/*</FONT></SPAN><SPAN style="COLOR: #008000"><BR><FONT face=Verdana size=2><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top>这里根本不需要typename.<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top>typename除用在模板声明中外,只能用于说明模板类的成员是一个类型.<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top>例如:<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top>template<typename T> class X {};<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top><BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top>// Another way<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top>template<class T> struct X {<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top>    typedef double DoubleType;<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top><BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top>    typename X<T>::DoubleType a;   // T::A is a type<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top>};<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top><BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top>而如果不是模板类,则不能用typename.这时,它并不是多余的,而是一定不能要的.<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top>例如:<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top>template<> struct X< X<int> > {<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top>    typename X<int>::DoubleType a;    //Error! X<int> is not a generic class<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top>    X<int>::DoubleType b;        //OK!<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top>};<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top><BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" align=top>我前面的代码也是这样的情况,ConvertType< UTF_8, UNICODE >已经是一个具体的类了,不要是模板类,所以ConvertType< UTF_8, UNICODE >::srcType前不能加typename.<BR><IMG src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" align=top></FONT></SPAN><SPAN style="COLOR: #008000"><FONT face=Verdana size=2>*/</FONT></SPAN></SPAN></DIV><img src ="http://www.cppblog.com/kb/aggbug/414.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/kb/" target="_blank">可冰</a> 2005-09-24 15:49 <a href="http://www.cppblog.com/kb/archive/2005/09/24/414.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>构思UTF-8解码模块</title><link>http://www.cppblog.com/kb/archive/2005/09/22/399.html</link><dc:creator>可冰</dc:creator><author>可冰</author><pubDate>Thu, 22 Sep 2005 15:24:00 GMT</pubDate><guid>http://www.cppblog.com/kb/archive/2005/09/22/399.html</guid><wfw:comment>http://www.cppblog.com/kb/comments/399.html</wfw:comment><comments>http://www.cppblog.com/kb/archive/2005/09/22/399.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/kb/comments/commentRss/399.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/kb/services/trackbacks/399.html</trackback:ping><description><![CDATA[<p style="font-family: verdana; font-size: 12px;">
想实现一个解码UTF-8格式文档为Unicode格式代码的"引擎",要用起来方便顺手.<br>但想了几天了,都没有一个合适的方案来实现.<br>唉......<br>今天先试着写了写,找找感觉,接着再想吧...<br>
</p><img src ="http://www.cppblog.com/kb/aggbug/399.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/kb/" target="_blank">可冰</a> 2005-09-22 23:24 <a href="http://www.cppblog.com/kb/archive/2005/09/22/399.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>std::wfstream是怎么支持宽字符的?</title><link>http://www.cppblog.com/kb/archive/2005/09/22/396.html</link><dc:creator>可冰</dc:creator><author>可冰</author><pubDate>Thu, 22 Sep 2005 14:47:00 GMT</pubDate><guid>http://www.cppblog.com/kb/archive/2005/09/22/396.html</guid><wfw:comment>http://www.cppblog.com/kb/comments/396.html</wfw:comment><comments>http://www.cppblog.com/kb/archive/2005/09/22/396.html#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://www.cppblog.com/kb/comments/commentRss/396.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/kb/services/trackbacks/396.html</trackback:ping><description><![CDATA[<span style="font-family: Verdana; font-size: 12px;"><br>
std::wfstream的定义为:<br>
</span><span style="color: rgb(0, 0, 153);font-family: Verdana; font-size: 12px;">typedef</span><span style="font-family: Verdana; font-size: 12px;"> basic_fstream&lt;<span style="color: rgb(0, 0, 153);">wchar_t</span>, char_traits&lt;<span style="color: rgb(0, 0, 153);">wchar_t</span>&gt; &gt; wfstream;<br>
在读取字符时:<br>
wfstream wfile( "wcharfile.txt" );<br>
<span style="color: rgb(0, 0, 153);">wchar_t</span> wch = wfile.get();<br>
按语义讲应该是读入两个字节内容的.但经输出检测,它却只读入一个字节,这样和fstream还有什么分别?<br>
到底在处理Unicode编码的文件时,应该如何使用宽字符流?</span><img src ="http://www.cppblog.com/kb/aggbug/396.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/kb/" target="_blank">可冰</a> 2005-09-22 22:47 <a href="http://www.cppblog.com/kb/archive/2005/09/22/396.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>类成员变量封装的问题</title><link>http://www.cppblog.com/kb/archive/2005/09/18/300.html</link><dc:creator>可冰</dc:creator><author>可冰</author><pubDate>Sun, 18 Sep 2005 10:19:00 GMT</pubDate><guid>http://www.cppblog.com/kb/archive/2005/09/18/300.html</guid><wfw:comment>http://www.cppblog.com/kb/comments/300.html</wfw:comment><comments>http://www.cppblog.com/kb/archive/2005/09/18/300.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/kb/comments/commentRss/300.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/kb/services/trackbacks/300.html</trackback:ping><description><![CDATA[<font style="font-family: Verdana;" size="2">  在类的设计中,对成员变量的封装是一个比较烦人的问题.什么时候应该提供读写的接口,什么时候应该声明为public,这样的问题有时候改几次也都不是很满意的.<br><br>  将对变量的读写操作封装起来以接口的形式提供,是有了一定的接口一致性.如果以后要在读写变量的操作内加入其它的操作,那么原有的代码就可以不加任何修改,只改这样的接口就行了.也就是对外部封闭了细节,使编程简单一点.
<br>但我也觉得不能用"一刀切"的方式将所有的成员变量都加以这样的封装,这样无疑会使代码增长(而且可能还有我所不知道的缺点).
<br><br>总的来说,<br>  对于要对外部提供应用的变量,最好以接口的形式提供.这样可以有比较一致的接口.<br>  而如果只是内部使用的话,且只是用于保存变量的值的话,直接声明为public会好一些.而若在内部也是相对地为其它类提供服务的话,也还是要声明为接口要好一些.<br><br>这里所说的内部和外部,只是相对来说的,并不只是针对某个类或程序而言.具体来说要根据代码的聚合程序来看.<br><br>最主要的原则还是要对具体的情况还要加以区别对待,根据实际情况不同而施以不同的应用.<br><br>===========<br>这样的问题主要还是靠编码经验的,如果有经验的话,可能凭感觉就可以随时决定的.<br>对于这个问题我也只是有这一点的初步见解(我几乎没有什么实际的编码经验),也不知道合不合适,希望有牛人可以加以指导.<br>
						</font><img src ="http://www.cppblog.com/kb/aggbug/300.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/kb/" target="_blank">可冰</a> 2005-09-18 18:19 <a href="http://www.cppblog.com/kb/archive/2005/09/18/300.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>目前C++可以实现跨平台吗</title><link>http://www.cppblog.com/kb/archive/2005/09/14/271.html</link><dc:creator>可冰</dc:creator><author>可冰</author><pubDate>Wed, 14 Sep 2005 15:30:00 GMT</pubDate><guid>http://www.cppblog.com/kb/archive/2005/09/14/271.html</guid><wfw:comment>http://www.cppblog.com/kb/comments/271.html</wfw:comment><comments>http://www.cppblog.com/kb/archive/2005/09/14/271.html#Feedback</comments><slash:comments>7</slash:comments><wfw:commentRss>http://www.cppblog.com/kb/comments/commentRss/271.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/kb/services/trackbacks/271.html</trackback:ping><description><![CDATA[<font style="font-family: Verdana;" size="2">大家都知道现在C/C++的编译是分为两个部分的,即编译和连接:源文件经编译后生成目标文件,然后再连接为可执行文件.<br>
我对这两个阶段要做的工作还没有了解,所以我现在可以这样设想(也有可能是无知的设想):<br>
以一种标准的方式定义目标文件的格式,使之在各操作系统上生成的目标文件完全一致,而且都可以在相应的平台上进行正确的连接.这样的话,就相当于是一个中间层次的可移植性了.其实,如果这样不行的话也可以像JAVA那样生成一定格式的"字节码"文件,然后再进行编译连接.<br>
如果可以将连接的一部分功能结合到操作系统内部,实现动态的连接,这样就可以实现类似动态装载的特性了.<br>
但这个要实现的话就需要有一个大的投资方或者开源社区自己的共同努力才能实现了.<br>
所以现在这样的想法还是空想吧.<br><br>
不过我想,事物都是发展的,我们的C++当然也不会例外的.我相信C++会在不久也实现动态及完全的跨平台的特性的.希望这一天不会太远!<br></font>

<img src ="http://www.cppblog.com/kb/aggbug/271.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/kb/" target="_blank">可冰</a> 2005-09-14 23:30 <a href="http://www.cppblog.com/kb/archive/2005/09/14/271.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>