不得不说,跟C/C++一贯的灵活的作风相反,C++标准模板库设计的极不灵活。STL的功能很难同新设计的代码融洽的融合在一起。
比如,你要写个快速排序的程序。由于选择了vector来表示数组。你不得不这样写:
void qsort(vector &v, int start, int len);
而原来只要写:
void qsort(int *start, int len);
多传了一个参数。而qsort里面是递归调用。这样明显损失了性能。
要不就这样写:
void qsort(vector::iterator start, vector::iterator end);
这样看起来又有点怪异。
学习过操作系统的程序员都知道,操作系统的文件缓冲区是同时放在两个链上的。应用程序写完数据,释放缓冲区后,缓冲区是同时处在av链和cache链上的。操作系统的刷新程序会继续追踪cache链,把没有存盘的数据写到盘上。然而STL组合不出能够处理2个链的链表。最后只能建两个list,把buffer控制区的指针,同时存到两个链表上。如何从两个链表上同时删掉一个buffer又成了问题。
要么在buffer控制块再加iterator?像这样:
struct buffer {
list<buffer*>::iterator av_chain;
list<buffer*>::iterator ca_chain;
int blk_no;
int size;
char *data;
};
在buffer 添加到list中的时候, 同时把指向它的迭代器存在它的数据成员里。
最后代码看起来是这个样子:
#include <stdio.h>
#include <list>
using namespace std;
struct buffer {
list<buffer*>::iterator av_chain;
list<buffer*>::iterator ca_chain;
int blk_no;
int size;
char *data;
};
char mem[16*3];
void print_node(buffer *b)
{
printf("[%d.%d]", b->blk_no, b->size);
}
int main()
{
list<buffer*> av;
list<buffer*> ca;
buffer *b;
int i;
for(i=0; i<3; i++) {
b= new buffer;
b->blk_no =i;
b->size=16;
b->data= &mem[16*i];
b->av_chain= av.insert(av.end(), b);
b->ca_chain= ca.insert(ca.begin(), b);
}
list<buffer*>::iterator av_it;
list<buffer*>::iterator ca_it;
av_it= av.begin();
while(av_it != av.end()) {
b = *av_it;
ca_it = b->ca_chain;
print_node(b); printf(": ");
while(ca_it != ca.end()) {
buffer *c;
c = *ca_it;
print_node(c); printf(" ");
++ca_it;
}
++av_it;
printf("\n");
}
}
它既多用存储,又慢,又容易出错,让人感觉到怪异。使用它造成的麻烦甚至超过了它带来的便利。
所以,很多项目都宣称禁止使用STL。当然在做小练习,或者测试程序时,偶尔用一下无伤大雅。当用于真正的项目时,需要评估一下,它是否会成为潜在的污染源,把你新写的代码都带坏。