Boost是极有才华的程序员们编写的C++库。Boost中的编程技巧、对C++及泛型的使用方式、以及其最终实现的效果都令人吃惊,甚至叹为观止。C++是强类型语言,有严格的类型检查。而Boost使用C++实现了弱类型的效果,着实在C++的墙上打了一个洞。
C++的强类型特征曾被视为一种优点。至今它仍然也是优点。严格的类型检查可以帮助程序员检测出代码中的错误,可以提醒程序员注意到数据的取值范围,可以规范程序员对变量的使用,并在一定程度上增加程序的易读性。可以说C++编译器对数据类型的检查筑起了一堵类型高墙,对变量任何错误的赋值、错误的使用都会被挡住,任何可能会出错的地方都会被提醒。比如下面的代码,在编译的时候是通不过的。
int i; i = \"I am a string!\"; |
这堵墙被筑在了编译器上,而在这堵墙之后,在程序的运行期,则几乎完全没有类型检查。不仅如此,类型信息似乎已经被抛弃了。程序不能在运行期得到数据的类型信息,因此也无法在运行期依据类型选择相应的操作。
比如在C++中就实现不了像下面这样的语句:
void * makePlace( para) { int len; len = para类型数据占用空间的大小; return 分配len个字节的内存; } |
void * makePlace (int para) { return new char[sizeof(para)]; } void * makePlace (float para) { return new char[sizeof(para)]; } |
如果有很多类型,那么就要写很多个makePlace.这些makePlace函数都是相似的。这只是一个简单的例子,事实上,有很多算法、结构都是可以应用到多种数据类型的,而为每种类型重写一堆代码,显然麻烦的很。
后来C++增加了泛型特征,可以在程序中使用模板。模板放在类型墙的前面,相当于一个变身器。把一个类型无关的算法放进来,生成一个符合类型法则的新算法,然后再放过到墙的另一边去。比如上面的makePlace代码,可以写成下面这样:
template<typename T> void * makePlace(T para) { return new char[sizeof(T)]; } |
也许在C++中引入泛型模板只是为了这个朴素的目的,让程序员少做些重复的工作。也许泛型标准的设计者当初认为这一点算不上类型墙上的裂缝,不会影响到C++的强类型特征。呵呵,想想IE浏览器忙着封堵的那些漏洞吧。
这世上总会有一些智慧让你惊。Boost就是这样的东西。
Boost没有修改C++的任何规则。它是一个完全符合C++规范的代码库。
但是看看这段代码:
int i; long j; X x; //假设X为用户定义的类 any anyVal=i; ... //use anyVal as a int value anyVal=j; ... //use anyVal as a long value anyVal=x; ... //use anyVal as a long value |
噢……这是什么,那个anyVal是什么类型的?any?它能除了int,long,X,还能赋值成别的类型么?这是C++程序么? 还是别的什么东东?
any是Boost的泛型指针,它确实可以赋值成任何类型。any其实是一个类。但any确实可以是任何类型。但单纯的any也什么类型也不是。当它是C#中的var好了。
再看看下面这段代码:
#include \"boost/assign/std/vector.hpp\" vector i_v; |
Boost做到了!
我想知道Boost是怎么做到的,我下载了Boost的源文件,我看到了Boost的源代码,我看到了复杂的模板,我看到了自己想像不出的高超技巧! Boost确实能在C++中实现这些代码。
事实上Boost实现的效果远不止文中描述的这些。Boost的源代码似乎也高于我的智慧,以至于我仍没有完全弄清楚它是怎么实现的,只能以后慢慢研究了。
C++的类型检查、语法规范等都很严格。它们像墙一样保护了C++程序的安全,并严格限制了C++的代码。Boost是使用C++编写的库,符合C++规范却让弱类型操作和奇怪的语句顺利穿过了这些墙。我觉得Boost不只是在发展C++,也是在C++自己的墙上打洞。