‹  返回课程

有哪些开源的项目完全或大部分是采用C++ STL来实现的?

课文
阅读量:133
技术范畴

三件事

  1. 为什么C++项目无法完全只使用STL?
  2. STL为什么内容那么单纯呢?
  3. 以leveldb为例,如何借助开源代码学习STL?
课前导言
在开源大行其道的当下,真是学习编程的最好的时代,如何通过过大量优秀的开源项目学习编程呢?方法之一是:不用过于神化大牛的代码。再怎么大牛,仍然需要写出大量朴实的代码。
有哪些开源的项目完全或大部分是采用C++ STL来实现的?
以leveldb为例,讲解如何通过开源项目学习STL。

问题附加说明:主要是想学习C++中的vector, list, stack,map 等用法,所以想看看相关的开源代码。

1. 为什么,C++项目很少 完全 使用STL实现?

“完全或大部分采用C++STL来实现”的项目……这样的要求让人很为难啊。要知道STL库和其它语言的标准库相比,最大的特点(是缺点也可以是优点),就是它比较纯,是在比较高的层面做的抽象。举个例子,它(至今/2017标准)就还没有网络库,图像库,那就意味着任何一个使用到网络或图片处理的C++项目,就不可能“完全或大部分”采用STL实现。

但如果说是“用到STL”,那就太多了。实际现在稍新的C++开源项目,基本能用到STL的就会用STL,并且也没有什么高大上,简简单单,和你和我等千千万普通C++程序员使用STL一样也并无两样——STL早就是C++程序中的基础工具,有时候候简直就是家里的插电口,水龙头,甚至电饭堡,你说什么大牛和小菜鸟来使用它们能有多大区别?

先看看 leveldb 的自我介绍:

github : https://github.com/google/leveldb

LevelDB is a fast key-value storage library written at Google that provides an ordered mapping from string keys to string values.

我下载看过google 家的 leveldb源代码,嗯,它至少用到 vector, set, map,string, algorithm(算法)等。后面会举leveldb的简简单单使用STL后些例子。

2. 为什么,C++的标准库(STL)不能包罗万象?

顺便说一下C++的标准库(STL)为什么并不包罗万象——事实上STL真的非常的“纯”,基本就只是包含算法、容器等高度通用、高度抽象的东西,为什么呢?

想想吧,C++为了兼容C付出了很大代价,这些代价总不能不换来好处吧?其中一个重要的好处就是和C语言一样,没有必要着急往库中塞进大量的功能(哪怕这功能在某个时间点突然非常的流行)。一门语言的标准库中没有流行的某个功能,它的程序员该怎么在自己的代码中拥有这些功能?程序员可是要拿代码实现功能以赚钱吃饭啊?别的语言还真的会难倒一大帮该语言的普通使用者,但C/C++从来没有这个问题存在。

这是什么?因为:

  1. 流行的操作系统多数是C写的,它们对外的功能API以前基本也是C程序,所以先是操作的API就不用再搞到语言的库里。
  2. 再接着,客观上这世界上大多数基础库(比如前面提到的网络和图像处理)都是C或C++写的,所以也很是没有必要将它们纳入语言的库。反倒是希望有更多其它语言编程者能用上。

别的语言你且大胆试试。以JAVA为例,没有NIO之前,恐怕十个Java程序员里只一个可能写出高质量的网络应用。当然我并不是在说C/C++程序员比Java程序员强,我是在说:其实大多数语言的编程者都写不了能被广泛使用的底层库,不管是Java还是C++还是Python,大家都是库的使用者居多,只不过C/C++程序员恰好捡了一个便宜:世上大多数底层功能程序库,是用C/C++写的,然后暴露为C的API。

很多基础库使用C/C++写的,这并不仅仅是历史现象,更不是“历史包袱”,它很可能是一个50年不变的基本规律了。比如新兴的深度学习,比较流行的Google家的TensorFlow也仍然是C++写的底子。

github: https://github.com/tensorflow/tensorflow

An Open Source Machine Learning Framework for Everyone https://tensorflow.org

有人问:“可是TensorFlow不也优先提供了Python的接口?”这问题其实和现在说的问题关系不大,因为事实很多很多C/C++写的库,都很快会有Python,PHP等优秀程序员将它们绑定各家的语言上面(Python就是这方面赢家);关系大是另外一面:“假设TensorFlow不提供Python、Java等语言的API……”那么,会不会有一大票Python和Java程序员由于深深折服于人工学习的美好前景,而踊跃学习C++语言?我相信会的——如果钱景也大的话——Object C 就是一个例子,但从更高层的语言折回C/C++这样相对底层的语言的过程,只能追求痛并快乐着了。

微软家的CNTK也是C++的底子,向上提供其它相对简单语言的API。

github: https://github.com/microsoft/CNTK/tree/master/Source

Microsoft Cognitive Toolkit (CNTK), an open source deep-learning toolkit https://docs.microsoft.com/cognitive-…

3. 关心主题:如何借助开源项目学习C++的STL

回到主题:题主同学,用STL的C++优秀项目多的是,但如果只用STL做的项目,那恐怕得是学校里的教学例子才能有。以levelDB为例,你也不担心会不会其它业务逻辑影响了你学习STL,认真看它用vector,map的方法,我想你应该会有一个感慨:原来STL用起也就这样子呀——很基础的工具而已。

比如在 helper/memenv/memenv.cc 源文件中 ,有一个类叫“FileState”,似乎是用于存储文件的状态——但如果只是出于学习std::vector的话,其实并不一定要管它的实质干什么活,只需看vector在这个类中的使用:

……
class FileState {
   ……
private:
   ……
   std::vector<char*> blocks_;
   ……
};
……

很清楚,这个类拿vector来存储很多char指针 呢……接着,既然是容器,作者是怎么放容器里塞一个个 char * 的呢?往前面一看,就有一个“Append()”方法:

Status Append(const Slice& data) {
    const char* src = data.data();
    size_t src_len = data.size();
    ……
       blocks_.push_back(new char[kBlockSize]);
    ……
};

没有什么意外的嘛,就是用push_back(),注意到char 指针是 new [] 得到的,所以现在可以在代码中搜索一下,应该会有 delete [] 的对应调用……果然在析构函数 ~FileState()中找到了,不过,这个私构函数是私有的,那说明……咦,另一个知识点来了,不过因为和STL无关,我们就不说了。要说的是我们在Append()函数的代码中看这一句:

……
memcpy(blocks_.back() + offset, src, avail);
……

vector::back()成员方法是干什么的?返回什么?另外,原来Google家的程序员,也和我们一样在,偶尔也会C的内存函数和C++的标准库混着用嘛——哈哈哈,如果你这么想,可就错了。C++新人要尽量少混用C的内存管理,玩到一定程度了,才好这样混搭。

所谓看名家项目的学习,经常也就这样,但这是有效的。当然,可能你的基础高,本处的例子对你可能过于简单。

至于TensorFlow,它也用到 vector, map, unordered_map, list, algorithm, string , set 等STL的组件,只是这家伙代码量有点大,不建议题主拿它来学习。

评论:

评论

课后导言
建议现在就去 github 网站,输入 C++ ……