第九期"Boost源码剖析:泛型函数指针类boost::fuction..."中的一个错误--作者按

pongba 2003-09-09 02:51:10

大家好,我是这篇文章的作者,非常对不起,在这篇"Boost源码剖析之:泛型函数指针类boost::function 之生死因果"中有个小小的疏忽,它在94页的“使用invoker的额外好处”一节,右版的中部(右版第二十五行),应该改成这样,以下是错误行附近的几行:

再看看它的第三行的那个typedef:
typedef typename detail::function::get_function_invoker1<
FunctionPtr,R,T0>::type invoker_type;
这里的R,T0是在具现化function模板时决议出的,你写的是function〈int(int)〉,于是R为int,T0为int。所以在本例中,上面的typedef被推导为:
// 第二十五行,改成下面这样,而原文是typedef function_invoker1〈int(*)(int),int,int〉type;
typedef function_invoker1〈int(*)(int,int),int,int〉 invoker_type;

再次说声抱歉!
...全文
134 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
pongba 2003-09-27
  • 打赏
  • 举报
回复
to tianxuejin(塘):
谢谢!
另外,我觉得写的已经比较清晰了,如果你还是不太懂,可以先看看一些泛型的入门书籍,我个人觉得有了C++模板的基本知识(这一点可以看《C++Primer》,如果你需要,我可以将中文电子版发到你的邮箱)就可以读一读侯捷的《STL源码剖析》其中对GP的释义较为清楚,并且可以让你有一些读源码的根基,然后,你就可以直接读《Modern C++ Design》(《C++设计新思维》(我就是这样读的),最后,如果你有足够的耐性,就可以自行解读BOOST代码了。
另外,给你一点建议,读原代码时可以先读其文档,BOOST的文档非常完备,然后,写下一小段例子代码,编译,运行,单步跟踪进去,然后一步一步解读,当然,你必须先由文档获悉某一个类(设施)的动机和用法,然后在跟踪的时候再去了解它是如何实现。
不管阅读还是跟踪BOOST的代码都是个很长的过程,如果要完全理解每一个细节更是难上加难,你首先要对C++语言机制有充分的了解(像《C++对象模型深度探索》这种书乃是必读)。
但是,真正理解了BOOST的原码是一种享受,关于这种享受我不用描述,以后你读懂之后自会明白。
强烈建议先读《C++设计新思维》,虽然论坛上有人指责侯捷的翻译谬误颇多,但我个人觉得翻译的不错(尽管我没读过原版),我从这本书中获益良多(当然,技术性越高的书对读者要求越高),并重燃学习C++的激情。
祝好运^_^!
RalphTien 2003-09-27
  • 打赏
  • 举报
回复
文章我读了,不过我不是个好读者没读懂
谢谢你将错误说出,我很敬佩你,负责。
pongba 2003-09-14
  • 打赏
  • 举报
回复
这全是我个人的错误和疏忽,所以我该向大家道歉,谢谢大家!
suntt 2003-09-13
  • 打赏
  • 举报
回复
向认真负责的你致敬
kxiangli 2003-09-12
  • 打赏
  • 举报
回复
感谢作者,文件已更新。
blue_laser 2003-09-09
  • 打赏
  • 举报
回复
that's all right!!
这上传的资包含一套我工作常用的模板库,及不需要MFC支持的excel操作接口,导出函数调用栈(dump stack)接口,可以直接用VS2008运行TestCodeLib.sln来根据unit test来了解用法。 ⑴ 需求(requirements) 重量级的BOOST非常强大,但有时候项目没有引入它,这时候我们需要自己的模板库。 BOOST is very powerful, but some projects have not include BOOST library. So we need out own template type trait library -- it is the responsibility of this lightweight library. 即使BOOST非常强大,但有些常用的功能其也没有,而经常性的代码又需要这些功能。比如把运行期数据转换为元程序需要的编译期数据。 Even if BOOST is very powerful,it can't still meet all requirements. e.g. convert runtime data into compile period data needed by metaprogramming. /*************************************************************************************************************************************/ ⑵ 益处(advantage) 此库抽象了一些常用的业务需求,可以避免大量的重复工作。 它是完全的并且是类安全的(没有强制类转换),如果使用错误将导致编译失败,从而提高了正确率(正确性由编译器保证)。 这个库的很多模板类推导不需要C++11的支持,这是一个大的优势(VS2010才开始支持C++11)。 this general library draws out some common business and avoid unnecessary repeat work. it is completed general and type-safe(without any type cast), mistake(s) will cause compile failure, so it improves correctness. In this library , type deduce need't C++11's support, it is big advantage. (VS2010 begin to support C++11) /*************************************************************************************************************************************/ ⑶ 用法(usage) 下载这个库后,使用VS打开.\CodeLib\testcase\TestCodeLib\TestCodeLib.sln,直接按F5启动,即可以看到许多单元测试的用法/测试用例的输出。 如果需要使用某功能,可以参考其对应的测试代码的用法。(每个功能文件.\CodeLib\include\MiniMPL\xxx.hpp,都对应一个测试文件.\CodeLib\testcase\MiniMPL\test_xxx.hpp) (这个库的使用及修改是完全自由的,只需要保留文件头的注释即可) usage: download this library, open .\CodeLib\testcase\TestCodeLib\TestCodeLib.sln with VS,you can see many usage/test output of unit test. every feature has according unit test file, it shows its usage. e.g. .\CodeLib\include\MiniMPL\xxx.hpp has according ".\CodeLib\testcase\MiniMPL\test_xxx.hpp" this library is all free, the only requirement is that you need to keep the comments in header file. /*********************************************************************************************************************************************************/ ⑷ 本库提供的主要功能介绍: major feature in this lib: ◆ [typeTraits.hpp] ★ 测试类的基本属性,比如IsConst/IsVoliate/IsRef/isAtomType/isBuildInType/isEnumType/IsIterator/IsPointer/isString/isInnerFloat/isArray/IsBaseDerive/.... ★ 转换类的基本属性,比如AddConst/AddVoliate/AddRef/AddPointer,..,RemoveConst/RemoveVoliate/RemoveRef/RemovePointer,... 这类功能是元程序库的基本支持组件,其它库(比如boost)也提供了,但本库时提供的检测属性更多。 ☆ detect type property. e.g.IsConst/IsVoliate/IsRef/isAtomType/isBuildInType/isEnumType/IsIterator/IsPointer/isString/isInnerFloat/isArray/IsBaseDerive/.... ☆ convert type basic qualifier,e.g. AddConst/AddVoliate/AddRef/AddPointer,..,RemoveConst/RemoveVoliate/RemoveRef/RemovePointer,... get type traits.e.g.const/voliate/ref/isAtomType/isBuildInType/isEnumType/isString/isInnerFloat/isArray/IsBaseDerive/.... It is base support component of metaprogramming system,it is similiar with BOOST , but this lib provide more. ◆ [typeConvert.hpp] ★ 实现类的修饰符转换。比如让输出参数类的修饰符(const/voliate/ref/*)和输入参数类的修饰符一样。 SameConst/SameVoliate/SameRef/SamePointer/SameAllQualifier/RefAdapter 应用场景:存取结构体的某类成员,当输入参数有某种const/voliate/ref修饰符时,通常要求返回值也有类似的修饰符。 ★ 当把"智能指针/stl迭代器/C指针/前三者嵌套"都视为指针时,其内的最终值(非指针值)是一致的,在模板函数,某些场景需要取得其最终的非指针值。 应用场景:转发模板函数,如 template void transmit(T p) { receive(p); } //void receive(int&); 如果transmit的传入实参p为指针(比如smartpointer::iterator>*或者vector::iterator), 但是转发的接收函数receive的形参为非指针(比如int&),理论上是可以实现转换的。 Get::finalValue接口提供了这种自动的转: template void transmit(T p) { receive(Get::finalValue(p)); } ☆ Convert type qualifiers,e.g. addConst/removeConst.. , keep same output qualifier (const/voliate/ref/*) with input type. apply scenario: get member of one structure object. ☆ Think "stlSmartptr/StlContainer::iterator/T*" as pointer, their inner non-pointer value is same. in some scenario, the final non-pointer value is needed. e.g. template void transmit(T p) { receive(p); } //void receive(int&); if real paremeter "p" is smartpointer::iterator>* or vector::iterator , but needed parameter by "receive" is int&, in theory it is OK. Get::finalValue provide this conversion: template void transmit(T p) { receive(Get::finalValue(p)); } ◆ [traverseTypeSet.hpp] ★ C++语法不支持模板函数/模板成员函数作为回调函数。本库采用了封装,可以支持模板函数的回调,并且支持最多7个可变参数(可以简易扩充参数个数)。 可以遍历一个TypeList或者枚举值范围CEnumRange,然后以满足条件的类回调用户的模板函数。 其广的应用场景即是把运行期数据以一种非hard-code的方式转化为编译期数据,从而满足元程序对编译期数据的需求。 ☆ C++ doesn't support template-based callback function. this lib package support template-based callback function(MAX 7 various parameters,easy to expand). It can traverse one TypeList or enum value , then call user's template function by suitable type/enum value. This feature converts runtime data into compile data to meet metaprogramming requirement without hard-code way, it is one big advantage. ◆ [functionTraits.hpp] ★ 获取任意类函数的各种特征,比如函数的所有参数Params_T,返回值类Return_T,对象类Object_T(如果是成员函数),第N个参数的类GetFunctionParam, 这些类都是包含修饰符(const/voliate/ref)的完整类。 这些组件对于操作函数非常重要。 ☆ get some traits of any function, include all parameter type "Params_T",return type "Return_T", host type "Object_T"(if member-function) , No.x parameter type "GetFunctionParam". this type include all signature qualifiers. This component is very important for metaprogramming based on function. ◆ 有时候STL的算法并不好用,经常是为了第三个参数需要自己写一个专用的琐碎的小函数。 虽然可以用std的bind或者boost的lambda,但是对于某些嵌套情况,用起来非常麻烦,这个库提供了下面的一些解决方式: sometimes STL algorithm is not good and it needs one traival function object(third parameter) , althrough std::bind/boost::lambda is available, but for some nest case, it is very hard to be used.this library provide below features: [function.hpp] ★ 把既有的多元函数转换为一元函数对象UnaryFunction。它通常应用于(比较/排序/遍历)算法的第三个参数。 ☆ convert existing multi-parameters into unary function, it is general used as 3rd parameter in general algorithm. e.g. stl::for_each [functionobject.hpp] ★ 把一些常用目的的函数封装成函数对象,比如"比较器/测试器" ☆ function object with special abstract targart. e.g. "comparer/Tester" ◆ [functionCreater.hpp] ★ 把多元函数封装为一元函数的帮助函数。(一元函数对象的类通常不易于书写) ☆ helper function to pack multi-parameters into unary function.(it is hard to write unary function object type) ◆ [paramPackage.hpp] ★ 实现了把任意多个(最多7个,可简易扩充),任意类的参数封装成一个参数以利于数据传递。 ☆ pack any number parameter (max 7,easy expand) into one parameter . it is easy to transfer. ◆ [classregister.hpp] ★ MFC的动态创建不是的,创造出来的对象必须是CObject的派生类,而且支持的创造方式单一,不够灵活有时候甚至不能满足需求。 本库里提供了一个的动态创建方式,可以以多种灵活的方式甚至用户自定义的方式来匿名动态创建对象,创建的对象基类可以由用户指定(必须存在派生关系)。 ☆ like MFC's DYNAMIC_CREATE, but the one of MFC is not general,the instance MUST be drived from class CObject, MFC dynamic creation has only one create way,sometimes it is not enough。 this library provides general dynamic create way, can create object by multiple ways , even customized way.and base class can be specified by user. ◆ [callbackWorker.hpp] ★ 最易于使用的回调函数是无参数的回调函数。 此功能可以把任意多个参数的多元(成员/非成员)函数封装成一个无参数函数,作为简单的回调函数。 ☆ best callback function is non-parameter function. This feature packs multiple-parameter function into one no-parameter function, it is easy to be used as callback function. ◆ [memberPtr.hpp] ★ 以统一的方式实现了任意级数的结构体成员的存和取,比如多级结构体嵌套。例子:a.m_b.m_c.m_d.....m_x,非常易于在模板设计使用。 ☆ access any level member of structure object by one unified way. e.g:a.m_b.m_c.m_d.....m_x,it is easy to be used in template componment. ◆ [anyObject.hpp] ★ 任意对象类(CAnyObject)。提供模板化的指针操作符,如果不支持用户指定指针,则转换结果为NULL,从而保证正确性。 ☆ package any object(CAnyObject), it operator function is template-based. if it doesn't support conversion, it return NULL. ◆ [dataset.hpp] ★ 把STL容器和经典数组封装成统一的形式,在使用上不再区别对待。对于C数组,将会自动检测越界情况。 ★ 可以使用初始化列表对数组,STL容器进行(反复)初始化。例如:vector a={1,2,3,45,2}; ☆ pack STL container and class array into unified object with several same interfaces. ☆ can initialize array/stl container with initalization list repeated. e.g. vector a={1,2,3,45,2}; ◆ [macroLoop.hpp] ★ 当多条语句的差别仅仅是一个数字时,可以利用提供的循环宏简化成一条宏语句,从而简化书写。用法可参见对应的单元测试例子。 ☆ if only one number is different in multiple statements, can use one macro loop to simplify them (one macro statement) usage refer to unit test. ◆ [mathOperator.hpp] ★ 的数学操作符。"equal/lesser/NotBinary/NotUnary/notEqual/lesserEqual/greater/greaterEqual及交换函数swap/swapif" ☆ general math operator. "equal/lesser/NotBinary/NotUnary/notEqual/lesserEqual/greater/greaterEqual and swap/swapif" /*************************************************************************************************************************************/ ⑸ 感谢及借鉴: 本库的占位符[placeHolder.hpp]借鉴于boost库,感谢boost库的大师们的灵感。 typelist来自loki库,但是把命名空间Loki改为MiniMPL以避免频繁的命名域切入/切出,感谢Andrei Alexandrescu的精彩演绎与启发. thanks and borrow: Args [placeHolder.h] comes from BOOST::MPL. thanks for BOOST team. typelist comes from loki lib with tiny modification(rename namespace loki to MiniMPL to avoid field switch frequently).thanks for Andrei Alexandrescu
译序 vii 英简繁术语对照 ix 目录 xvii 序言 xxi 致谢 xxiii 导读 1. 让自己习惯c++ accustoming yourself to c++ 条款01:视c++ 为一个语言联邦 view c++ as a federation of languages 条款02:尽量以const, enum, inline替换 #define prefer consts,enums, and inlines to #defines. 条款03:尽可能使用const use const whenever possible. 条款04:确定对象被使用前已先被初始化 make sure that objects are initialized before they're used. 2. 构造/析构/赋值运算 constructors, destructors, and assignment operators 条款05:了解c++ 默默编写并调用哪些函数 know what functions c++ silently writes and calls. 条款06:若不想使用编译器自动生成的函数,就该明确拒绝 explicitly disallow the use of compiler-generated functions you do not want. 条款07:为多态基类声明virtual析构函数 declare destructors virtual in polymorphic base classes. 条款08:别让异常逃离析构函数 prevent exceptions from leaving destructors. 条款09:绝不在构造和析构过程调用virtual函数 never call virtual functions during construction or destruction. 条款10:令operator= 返回一个reference to *this have assignment operators return a reference to *this. 条款11:在operator= 处理“自我赋值” handle assignment to self in operator=. 条款12:复制对象时勿忘其每一个成分 copy all parts of an object. 3. 资管理 resource management 条款13:以对象管理资 use objects to manage resources. 条款14:在资管理类小心coping行为 think carefully about copying behavior in resource-managing classes. 条款15:在资管理类提供对原始资的访问 provide access to raw resources in resource-managing classes. 条款16:成对使用new和delete时要采取相同形式 use the same form in corresponding uses of new and delete. 条款17:以独立语句将newed对象置入智能指针 store newed objects in smart pointers in standalone statements. 4. 设计与声明 designs and declarations 条款18:让接口容易被正确使用,不易被误用 make interfaces easy to use correctly and hard to use incorrectly. 条款19:设计class犹如设计type treat class design as type design. 条款20:宁以pass-by-reference-to-const替换pass-by-value prefer pass-by-reference-to-const to pass-by-value. 条款21:必须返回对象时,别妄想返回其reference don't try to return a reference when you must return an object. 条款22:将成员变量声明为private declare data members private. 条款23:宁以non-member、non-friend替换member函数 prefer non-member non-friend functions to member functions. 条款24:若所有参数皆需类转换,请为此采用non-member函数 declare non-member functions when type conversions should apply to all parameters. 条款25:考虑写出一个不抛异常的swap函数 consider support for a non-throwing swap. 5. 实现 implementations 条款26:尽可能延后变量定义式的出现时间 postpone variable definitions as long as possible. 条款27:尽量少做转动作 minimize casting. 条款28:避免返回handles指向对象内部成分 avoid returning “handles” to object internals. 条款29:为“异常安全”而努力是值得的 strive for exception-safe code. 条款30:透彻了解inlining的里里外外 understand the ins and outs of inlining. 条款31:将文件间的编译依存关系降至最低 minimize compilation dependencies between files. 6. 继承与面向对象设计 inheritance and object-oriented design 条款32:确定你的public继承塑模出is-a关系 make sure public inheritance models “is-a.” 条款33:避免遮掩继承而来的名称 avoid hiding inherited names. 条款34:区分接口继承和实现继承 differentiate between inheritance of interface and inheritance of implementation. 条款35:考虑virtual函数以外的其他选择 consider alternatives to virtual functions. 条款36:绝不重新定义继承而来的non-virtual函数 never redefine an inherited non-virtual function. 条款37:绝不重新定义继承而来的缺省参数值 never redefine a function's inherited default parameter value. 条款38:通过复合塑模出has-a或“根据某物实现出” model “has-a” or “is-implemented-in-terms-of” through composition. 条款39:明智而审慎地使用private继承 use private inheritance judiciously. 条款40:明智而审慎地使用多重继承 use multiple inheritance judiciously. 7. 模板与编程 templates and generic programming 条款41:了解隐式接口和编译期多态 understand implicit interfaces and compile-time polymorphism. 条款42:了解typename的双重意义 understand the two meanings of typename. 条款43:学习处理模板化基类内的名称 know how to access names in templatized base classes. 条款44:将与参数无关的代码抽离templates factor parameter-independent code out of templates. 条款45:运用成员函数模板接受所有兼容类 use member function templates to accept “all compatible types.” 条款46:需要类转换时请为模板定义非成员函数 define non-member functions inside templates when type conversions are desired. 条款47:请使用traits classes表现类信息 use traits classes for information about types. 条款48:认识template元编程 be aware of template metaprogramming. 8. 定制new和delete customizing new and delete 条款49:了解new-handler的行为 understand the behavior of the new-handler. 条款50:了解new和delete的合理替换时机 understand when it makes sense to replace new and delete. 条款51:编写new和delete时需固守常规 adhere to convention when writing new and delete. 条款52:写了placement new也要写placement delete write placement delete if you write placement new. 9. 杂项讨论 miscellany 条款53:不要轻忽编译器的警告 pay attention to compiler warnings. 条款54:让自己熟悉包括tr1在内的标准程序库 familiarize yourself with the standard library, including tr1. 条款55:让自己熟悉boost familiarize yourself with boost. a 本书之外 b 新旧版条款对映 索引

6,909

社区成员

发帖
与我相关
我的任务
社区描述
《新程序员》读者俱乐部
其他 其他
社区管理员
  • 《程序员》杂志社区
  • SoftwareTeacher
  • 《新程序员》编辑部
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧