《Modern C++ Design》Loki库读解四

anrxhzh 2002-10-31 01:11:26
我在CSDN上的账号被冻结了,无法发表评论,谁能待发一下,相赠50分。


--------------------------------------------------------------------------


学而不思则惘,思而不学则怠。


从技术上看,loki的基石是typelist,这一个非常简单的概念:
template <class H, class T>
struct typelist
{
typedef H head;
typedef T tail;
};
typelist并不是loki的首创,它来自于Metaprogramming,但是把它运用于设计模式则是Andrei Alexandrescu的天才。
在我看来,loki是Generic Programming的实作,它和STL有亲缘关系。有的人把STL称作参数化的过程和类,我觉得这只是表面现象,没有人会把OO称作vtable,因为这里面蕴含着新的方法论。

STL解决了数据结构和算法的抽象问题,这是传统OO的难题。loki试图解决模式的抽象问题,这是一项创举,STL和loki都有自己的一系列术语,OO中的类在这里被泛化了。以“我爱你”为例,OO能够很好地表达我和你的概念,不能很好地表达爱这个概念,这就是GP的用武之地。HierarchyGenerators可以运用在abstrct factory中,实际上就是表达了“创建”这个概念。我觉得loki和STL的不同就是后者存储和操纵的是数据,前者存储和操纵的是类型;后者是运行时,前者是编译时。
...全文
537 41 打赏 收藏 举报
写回复
41 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
见招拆招 2003-02-21
mark
  • 打赏
  • 举报
回复
jack2002 2002-11-08
模式只是一个抽象,同样也有一定的限制的,事物的抽想是有层次的可以被不断的细分,如果坚持要无论何事都要用模式来处理,等于是一个“永动机”的理想错误还是要,在一定范围,一定情况下来使用。

模式肯定是一种新方法,但是他不是我们的全部。

控制的使用,这才是关键!
  • 打赏
  • 举报
回复
jack2002 2002-11-08
我认为,所谓的gp只是在一定范围内的,至于范围的大小这是决定是否可以实现的条件。任何事物的实现都是有条件的,gp也不例外,现在提出的模式只是一种概念如果要实现的话肯定要有很雄厚的技术职称更是在一定程度一定范围里使用而不是overuse or abuse.任何东西都有可能被 over or abuse 我们要做的是如何受
控制的使用。
  • 打赏
  • 举报
回复
papercrane 2002-11-07
//hand Elminster :-)
我觉得关键在于有没有持续的需求,希望重复的在程序中实现dp这一相对低效的工作能被机器代劳。只要有这样的需求,完成这样的飞跃是有可能的,至于最终是以什么形式实现倒无关重要。在目前的编译器限制下难以实现,并不等于不能做或者没有必要做,如果这样的思想实验(相对于设计编码运行实验而言)显示dp library具有足够的必要性,为这种想法而修订标准并非不可想象的事情。目前我想对dp的形式化描述是我们首先要做的工作,然后要解决的问题是为了高效优雅的实现这些描述,我们对编译器有什么期待。简单来说,我们不是装修外墙,而是加建楼层。
  • 打赏
  • 举报
回复
papercrane 2002-11-07
to Elminster:
周围的人都叫我起重机,你是为我正名的唯一一个,来广州敲我一顿好不好:)
  • 打赏
  • 举报
回复
Elminster 2002-11-07
To 绯雨闲丸

对呀,设计模式本身到目前为止还只是一个经验总结式的东西,两个不同的人说起同一个模式来想的还不是同一个东西,你如何让没有智能的计算机来处理模式的自动生成?

正因为如此,才要引入模式的形式化的描述,首先你得精确定义一个模式是什么,然后精确定义这个模式的各种衍生变形及扩展,最后才是自动生成。拿哈希表做例子,首先定义什么是哈希表:键和值之间通过哈希函数映射的线性表,然后再定义各种不同的冲突处理方式:链地址、再哈希、线性探测 …… 有了这么一套完整的精确的定义,今天的 SGI STL 才能让你用几个模板参数就自动的生成出一个能工作的 hash_map 来。

至于说到形式化的描述需求 …… 这就是从古到今程序员所做的唯一的事情啊,把用户提出的模糊的需求形式化的描述下来 ——— 结果就是软件。

To papercrane

纸鹤就纸鹤吧,纸起重机 ……
  • 打赏
  • 举报
回复
papercrane 2002-11-07
to SHIZUMARU(绯雨闲丸):
有同感。大家何不描述一下各自曾遭遇过的对各种dp的要求以及实现上的挫折(我觉得好像在引导客户作需求^_^)。
  • 打赏
  • 举报
回复
SHIZUMARU 2002-11-07
to 伊尔明斯特:

你的这种希望,听起来比较玄。对于设计模式,本来每个人的想法都是不一样的。还以Singleton为例,有人只想要一个最简单的;有人想得多一点,希望能有一些OO的特性在里面;有人要得更多一点,希望能thread-safety。每个人都说Singleton,其实心里想的都不是同一个东西,还谈什么形式化描述?

或者可以换个角度来说,就是我们对复用的期望值太高。自己脑子里面想的东西(或者叫需求)根本都没办法形式化,就希望能有一些东西可以复用,我很直觉地就觉得这不大可能。仍以Singleton为例,简单的Singleton(例如GoF版)招人骂,因为它不好用;复杂的Singleton(例如Loki版)还是招人骂,因为它太复杂。每个人的想要的东西就不一样,怎么可能有一个库来适应所有人的要求呢?

所以(顺便回应纸起重机),首要的问题恐怕还不是形式化描述设计模式,倒是形式化描述需求。不过,设计模式也可以(以某种形式)用来描述需求。再申发下去,就out of my control了,就此打住。
  • 打赏
  • 举报
回复
anrxhzh 2002-11-07
很有道理。STL的诞生有三个先决条件:一是前人对算法和数据结构的理论研究已经建立了非常坚实的土壤;二是STL的创造者在这片土壤上对算法和数据结构的分类学有着独到的建树;三是当时的C++提供了合适的表达工具。目前在设计模式领域恐怕连第一个条件都还没有满足。
  • 打赏
  • 举报
回复
Elminster 2002-11-06
用 template 展开之类的方法来实现 pattern ,我认为是做不到的,至少在目前。原因也比较简单,对于 pattern 还没法精确的,形式化的描述它。什么时候那 23 个模式可以象 stack、qsort 一样用形式化的语言非常精确的描述出来了,那时候我们就可以期待用很少的几行东东指明:我这里要一个 Decorator,这里要一个 Chain of Responsibility ……

PS:cber 你什么时候成了 GP 版的版主了?
  • 打赏
  • 举报
回复
anrxhzh 2002-11-05
我并不认为Loki是想用GP代替OO,恰恰相反,我认为Loki是试图用GP来表达模式。设计模式当然可以包含OO,但并不局限于OO,但是不管一个模式是否包含OO,都不影响用GP来表示它。我现在的看法是:GP和OO是两个不同的东西,他们从来就没有发生过矛盾,将来也不会发生矛盾。

-------------------------------------------------------------------
根据我的理解,Loki库沿用的是Metaprogramming的思路,当你一遍又一遍地运用同一个模式时,必然会写出一系列非常相似的代码,其中肯定是有一些规律性的东西的。Loki认为它可以用模板技术自动生成精确地包含了特定模式的C++代码,如果该模式要求Dynamic Dispath,它当然要生成包含Dynamic Dispath的代码。换句话说,模板类生成的类当然可以是传统的多态类,这里面并不存在矛盾。我认为Loki的思路是很自然的,这里的关键是设计模式能不能用代码库来表达?对库的基本要求是通用而又不失精确性,这里的精确性对于STL来说就是不能丧失效率,对DP来说就是不能丧失灵活性。
-------------------------------------------------------------------
我记得Alexander Stepanov说过GP和Static Type没有任何关系。我曾对这句话非常困惑,一位网友就此谈到:
hello, anrxhzh, I agree with you. It absolutely can't load the file
dynamically the same way as we mention in Think in c++ because GP use static type check. But, it does't matter, because you can overload >> and << operator to realize dynamic file loading and type checking.The key point of GP is that it offer a higher abstraction than that of normal OO design, and give us a clear, easy to extend interface.You mentioned that there is no relationship between GP and static type. It's right because they deal with different things. How did you think if a template class in which a virtual function is defined?


  • 打赏
  • 举报
回复
babysloth 2002-11-05
mcd核心思想并非所谓分离编译期计算和运行期计算,请注意这本书的副标题
generic programming and design patterns applied
他是希望将template用于实现模式,然而根本不为C++社群所接受
bs的反对是一个例子,标准委员会发起的boost两次拒绝loki加入又是一例,
andrei本人也非常无奈,可以说,这不是未来的方向。andrei本人计划的新书名叫The Return of C++,不知道会不会有所改变呢,呵呵

至于楼上提到的,恐怕是最近几年兴起的template metaprogramming,
在loki中看到的几乎所有metaprogramming技术,都并非loki首创,基本来自comp.lang.c++.moderated;且boost中的实现好得多,也更为C++社群接受。

现在不少C++编译器对模板的支持非常好,gcc就不错,而合并了kcc的intel c/c++编译器表现也相当出色。有了Lippman加盟的vc自然不会让我们失望。事实上,基于expression template技术的类库已经遍地开花,bs来华的讲座就提到了这一点,他就展示了MTL库。

我个人以为,bs强调的是各种paradigm保持平衡,不要期望任何一种是万灵丹。如果想用GP代替OO的一切,未免不太现实。andrei向我们展示的,仅仅是C++可以做什么,而并非C++要这么做。看看他对min/max的实现,您会用吗?用他自己的话说,他更像是在做挑战,在做一个登山者,而并非一个为我们普通程序员开路的人。不过话说回来,我还是很欣赏他提的policy和scope_guard(虽然bs在TC++PL里早就写了),呵呵。
  • 打赏
  • 举报
回复
eroc 2002-11-05
同意middle兄的看法。
C++ templates 根本上就是一可参数化类型实现手段。脱离这一根本,利用templates搞编译期计算的做法就是overuse了。当然,这不是说编译期计算是无意义的(相反,它的意义非常大),只不过目前的C++ templates 并不支持这样的做法。不知道以后新版C++会不会在这方面有大的步伐。但估计近期内是不会有的 (真正的大的变化至少要搞到5-10年之后才能见到?)。另外一个是要注意overuse和abuse(滥用)区别, abuse是肯定有害的。overuse就不一定了。

Andrei对C++的贡献是很大的,Andrei可以说是当代最富有创造力的两个C++程序员之一。对Andrei的贡献, 非常同意anrxhzh(百宝箱) 兄的看法: loki其实真正展示给我们的是一种思想 (他那本书才是真正的"C++编程思想") - 概括地说,什么编译期计算我们可以做,如何做,和这么做的意义,等等 - 通过Loki非常具体地展示出来.

  • 打赏
  • 举报
回复
anrxhzh 2002-11-05
看起来Generic Pattern Implementations (GPI)能够起多大的作用,取决于实现者和使用者对特定模式的认识深度,而GPI本身是当前条件下极具创造性的构想,在我看来简直是极致了。
  • 打赏
  • 举报
回复
anrxhzh 2002-11-05
"To Code or Not to Code II", C++ Report, March and June 2000, in co-authorship with Dr. John Vlissides.
"To Code or Not to Code I", C++ Report, March and June 2000, in co-authorship with Dr. John Vlissides.

http://www.moderncppdesign.com/publications/main.html
  • 打赏
  • 举报
回复
huxw 2002-11-05
另外白活两句, 当初j. v.(就是gof里面的一个, 偶不记得名字了)对mcd似乎很是欣赏.......记得还看到过他和andrei合作的两片东西, 好像是C++ report的专栏来着.....
  • 打赏
  • 举报
回复
huxw 2002-11-05
中午本来想发言的, csdn抽风, 结果白写了.....wuwu.....没有天理....

singleton这样的模式, 现在还有找到完美的做法, 哪里谈得上抽象...所以一点也怪不得loki.. ;-)

而且也不是说loki实现的模式不好, 但是它没法实现模式组合的模式, 或者模式组合的模式组合的模式..或者......., 写一个东西, 不是有一个模式就用一个模式. 而是大家相互影响的. 所以loki库中最成功的, 不是模式, 而是基于policy的功能模块的实现, 比如smart_ptr(//hand 虫虫).

偶不是说pattern不能用模版实现, 不是这个意思. 偶是说, pattern这个东西没法拿来做库. 不能用户来主导设计, 而是只能作成一个framework来引导用户进行设计, 大致和mfc那样.

关于template expression, 其实也不是特别的复杂. 说是不提倡自己动手写, 是怕你累着, 小心一点, 自己写到也不是什么大不了的事情....

像一个静态的CountChar之类的东西, 我觉得没什么困难的, 模版的递归调用最擅长处理此类问题, 如果有问题, 那也是编译器能支持模版嵌套的强度的问题.
  • 打赏
  • 举报
回复
eroc 2002-11-05
CountLetter<aStringLiteral, 'a'>::value;

这只是我期望的, 用来说明我要的功能. 这么个"CountLetter"是不可能实现的. 这个功能倒是能实现的, 但语法就没那么干净了, 可以说是惨不忍睹.
  • 打赏
  • 举报
回复
babysloth 2002-11-05
然后呢?有什么不对的吗?
您是指缺乏template typedef带来的语法?
  • 打赏
  • 举报
回复
eroc 2002-11-05
比如: 给定任意字符串常量, 统计里面某个字母的个数. 举例:

const char* const aStringLiteral = "abaafdfkaajdlaeajflafda";
...
CountLetter<aStringLiteral, 'a'>::value; // 希望value是个常数, 等于'a'在aStringLiteral中的个数. 如何实现CountLetter<...>?
  • 打赏
  • 举报
回复
加载更多回复(21)
发帖
工具平台和程序库

2.4w+

社区成员

C/C++ 工具平台和程序库
社区管理员
  • 工具平台和程序库社区
加入社区
帖子事件
创建了帖子
2002-10-31 01:11
社区公告
暂无公告