stl如果开o2_如何自己写一个STL(上)
昨天,我的一個小項目 MyTinySTL 發布了 v2.0.0 版本,宣布這個項目告一段落。這個項目從去年暑假開始動工,至今已經過了一年多了,期間完成過多次重構,這一次算是第三次重構,進行了非常多的修改。可以看到,提交數已經超過 1000,當然我沒有特地湊這個數字,而是我最后一次 merge 之后,剛好就是一千了!而代碼量,現存下來的不是很多,2W 余行,但是期間 debug 過的代碼量,遠遠超過這個數字。所以我也不會去求 star,但是能給就最好了!(〃’▽’〃)
其實這期間,有人向我反饋過,我有沒有一些筆記什么的。然而一直沒有什么時間做。我很高興能夠有人看一眼我的拙作(其實我收到的反饋也只有兩個人),但更重要的是我自己的收獲。所以現在,我基本也可以棄掉這個坑,去學習其它的東西了,就來說一些自己實現一個 tinystl 的感想吧!
為什么要自己實現一個 STL
這個問題在不同時候、不同的人身上,會有不同的意義。對于我個人而言,當初我的想法是什么呢?其實我很早之前就已經接觸過和自學過 C++ 了,但那畢竟是太小的時候,以至于很多東西都不懂,所以也可以說根本不會。但也不是完全沒有幫助,對我的幫助就是沒有 “如何入門C++” 這一說。因為基本的語法之類的我也知道,只是不明白為什么這樣寫。所以等我到了大學,我只花了兩天時間把幾年前的一本 C++ 入門書翻一翻,就大概復習了一遍 C++ 的基本語法了。當然,書是 09 年買的,所以那個時候還沒有 C++11,我也不會模板。所以自然跟很多初學者會產生同樣的疑問:C++ 能做什么?
然后大一的時候,練習過一些競賽題,用 C++ 寫。那時候就只知道,C++ 有個東西,叫 STL。#include 后你可以直接用 sort,不用自己寫;#include 后你可以用 vector,還不需要管它的長度;#include 之后可以用 map,相當于自己用兩個 raw array 來模擬……但是,為什么就可以用呢?為什么要寫成 vector 呢?這個有什么用呢?……那時候我還真不懂,連模板都沒聽過。
后來,我希望找一些簡單的練手項目,來練習一下 C++。但是好多人提的練手項目,我都看不懂,不知道他們在說什么,不知道初學者會不會也有這樣的感受。然后我就看到有一個人說:實現一個 tinystl 。哎,這個我好像知道,然后看了看別人附上的鏈接,里面有 Vector,有 List,emmmmmm…我當時對 STL 的理解就是,把數據結構封裝成庫了嘛,就想著數據結構還是能看懂的,而且也希望了解一下 C++ 里面那些玩意兒是怎么實現的,立馬就決定了 —— 就寫一個 tinystl 了!
準備知識
決定好了,怎么開始呢?我看到很多人都提到一本書 —— 《STL源碼剖析》,于是我自然也去買了這本書來看。當然現在讓我推薦,我對這本書持保留態度。確實這本書很老,而且用的是 SGI 的實現。但是這本書是讓我認識到了什么是 STL,STL 的構成等等等等。但是對于現在入門 C++ 都有什么 Primer 什么 Plus 什么 5 的,那么好的資源,應該這些東西都懂,根本不需要再看那本書了。書中提到,還需要一些模板的基礎知識,所以我就在網上學習了一下 C++ 模板的基礎知識,也是那種很零碎的一篇一篇博客,但知識夠用了,因為 STL 中用到的技巧并不復雜。當然現在讓我推薦 C++ 模板的教程的話,我自然會安利一波空大(空明流轉)的這個 CppTemplateTutorial,還有我的 PR 呢,只不過空大太忙了沒時間看。然后有了基礎了解之后,就差不多可以動手了。當然這一篇文章我不會開始講如何去寫,我想先說說我個人的感受。
實現過程
說實話,tinystl 的規模可以說是要大就大,要小就小。小的可以很簡單,大的可以很復雜。剛開始我也沒想過有多少,也沒想過要寫得完善,沒想到最后卻跟這辣雞標準庫越來越接近…比如接口,會修改得跟標準一致,以及異常安全保證,也會盡量遵守標準。當然這也不全是壞事,因為你去實現一遍,你就能感受到很多設計極其不合理的地方…這樣你再噴的時候才能有理有據。
當然,實現過程免不了 “借鑒” 或者 “抄襲”,畢竟很多東西讓你從 0 到 1,是很難做到的。但是你有了這個從 0 到 1 的基礎之后,再往后 從 1 到 2 甚至到 n (n > 2),都是容易得多的。比如你多寫幾個 algorithm 里的函數,你就會發現套路其實都差不多的,大部分函數你都可以獨自寫出。只有少部分需要用到智商。容器的話,數據結構間的差異還是蠻大的(不要扯什么 set/map,我說的不是這個意思),所以具體實現有許多不同。但整體框架都保持一致,都是 constructor, destructor, operator=,迭代器相關、容量相關、插入刪除相關,有些可能還有容器特有的操作等等。
所以不要擔心它多,擔心它難,只要開始去做,把開始的工作做好,剩下來的就是不斷的糊各種各樣的東西而已。當然,非常重要的一點,一定要在做之前對各種數據結構的原理了然于心。
有沒有用
也會有人說,現在學 C++ 的造 STL 泛濫,各種 github 上抄來抄去,有什么用?當然啦,有沒有用,這是很難講的。你覺得有,可能就有;你覺得沒有,也未必沒有。也要考慮你出于什么目的,比如你是一個可以獨自用 C++ 造出一個什么高性能高精度運算庫,什么高性能 DB,什么游戲引擎的,對什么 template,什么 tag dispatch,什么 SFINAE 等技法早就爛熟于心的,你說造一個 tinystl 干嘛?別人根本就不屑用標準庫的了,都有自己的一套。而如果說你是想提升 C++ 技能,學習 C++ 技巧,造一個 tinystl 其實并沒有用到太多的技巧,講真,大部分時間都是去堆砌、堆砌、堆砌,然后找 bug、找 bug、找 bug。
那么你說,造它有什么用呢?我個人覺得,學習不能抱著太強的目的,因為學習的過程本身就是未知的、曲折的、探索的,其中很有可能伴著失敗,你要是抱著很強目的心去學習,學不到的,還有可能會走火入魔(霧)。
而于我而言,我完成這個,對我的幫助還蠻大。但主要不是在 STL 這一塊。因為我在寫這個之前,很少用多個頭文檔,源文檔這樣的,都是一個文檔全搞定。所以這可以說是第一個“工程”類的項目了吧?所以我學到了很多代碼結構,工程方面的東西。包括但不限于頭文檔 include 保護、代碼規范等。說真的在代碼規范這方面我為此看了非常多,包括但不限于 Google C++ 代碼風格、LLVM 代碼風格等。盡量向好的代碼看齊。也為此進行過多次重構。第二,接觸到了許多工具,比如 git,camke,ci 等。剛開始我也不會用 github 的,在本地寫了,然后在網頁上打開去一個一個的修改。后來我才知道這是個多么蠢的姿勢…然后是接觸到 cmake,我承認我到現在也不完全會用,但已經比之前好多了…還有 ci,也是最開始根本不會用,文檔看不懂,折騰了很久,到現在勉強可以使用。第三,了解到很多概念。比如跨平臺跨編譯器,編譯器版本,編譯參數等等非常多的東西。為了能測試在其它平臺上的運行,還折騰了一段時間雙系統,linux 什么的。以前只會在 VS 里面 Ctrl + F5,現在至少可以用 g++ test.cpp -O2 -std=c++11 -Wall -Wextra -Wno-sign-compare 這類的東西而且明確的知道每個參數的意義。
所以,這期間其實是很長的一段時間,不一定都是因為我做這個我才了解,也有可能做別的我也能了解,但有些我知道了我就有一個東西讓我去用上。因此我認為我造一個 tinystl 就是有用的。因為它培養了我很多良好的工程習慣,讓我后面在寫各種東西的時候,能夠比較輕松自如,知道怎么去著手。
所以如果你已經有過這些經驗,你去造一個 tinystl,你可能不會像我一樣收獲那么多,但如果你想做,那就做唄,反正標準庫又不好用(逃
總結
總結其實都在上面的話里,讓我再總結一遍,那就幾句話吧:給個 star
我不懂模板,想搞清楚 STL 的實現,所以就做了
如果你想做,你需要了解過 STL,使用過 STL,并對其中的數據結構的原理非常熟悉
“抄襲” 很正常啊
你覺得有用就有用,你想做就做,管別人怎么說干嘛
總結
以上是生活随笔為你收集整理的stl如果开o2_如何自己写一个STL(上)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: powerbi 线性回归_Power B
- 下一篇: php怎么输出倒三角_JS数组中,两两比