2012-08-14 105 views
8

我不明白爲什麼他們在C++ STL中分離算法,迭代器和容器。如果它在各個地方大量使用模板,那麼我們可以使用模板參數將所有東西放在一個地方。爲什麼在C++ STL中分離算法,迭代器和容器STL

我得到的一些文本解釋了迭代器可以幫助算法與容器數據進行交互,但是如果容器公開某些機制來訪問它所擁有的數據呢?

+1

我不明白你寫的一個字。 :( – Mehrdad 2012-08-14 06:51:57

+0

好吧抱歉引起的混淆,我的意思是我們有不同的容器,迭代器等類。我想知道如果我們將所有類放在一個類中使用模板,容器有數據,他們可以暴露一些接口,看看有什麼不對它或修改。爲什麼它們是分開的?我的意思是爲什麼有不同的迭代器,算法等。 – Rahul 2012-08-14 06:54:31

+3

[This question](http://stackoverflow.com/questions/10380612/principles-behind-stl-design)可能會給你一些與STL的創建者Alex Stephanov一起[本次訪談](http://www.sgi.com/tech/stl/drdobbs-interview.html)也包含一些見解。 – 2012-08-14 06:56:09

回答

22

M隨着集裝箱+ N算法,人們通常需要M * N代碼段,但與作爲「粘合劑」的迭代器,這可以減少到M + N件代碼。

實施例:運行2種算法3升的容器

std::list<int> l = { 0, 2, 5, 6, 3, 1 }; // C++11 initializer lists 
std::vector<int> v = { 0, 2, 5, 6, 3, 1 }; // C++11 initializer lists 
std::array<int, 5> a = { 0, 2, 5, 6, 3, 1 }; 

auto l_contains1 = std::find(l.begin(), l.end(), 1) != l.end(); 
auto v_contains5 = std::find(v.begin(), v.end(), 5) != v.end(); 
auto a_contains3 = std::find(a.begin(), a.end(), 3) != a.end(); 

auto l_count1 = std::count(l.begin(), l.end(), 1); 
auto v_count5 = std::count(v.begin(), v.end(), 5); 
auto a_count3 = std::count(a.begin(), a.end(), 3); 

要調用只有2個不同的算法,並且只具有用於3個集裝箱代碼。每個容器都將begin()end()迭代器傳遞到容器。即使您有3 * 2行代碼來生成答案,但只有3 + 2件功能需要編寫。對於更多的容器和算法,這種分離將大大減少代碼中的組合爆炸,否則會導致:在STL中有5個序列容器,8個關聯容器和3個容器適配器,並且有近80個算法單獨在<algorithm>(甚至不包括在<numeric>中),因此您只有16 + 80而不是16 * 80,代碼減少了13倍! (當然,並非每種算法都適用於每個容器,但重點應該清楚)。

迭代器可以分爲5類(輸入,輸出,轉發,雙向和隨機訪問),根據迭代器的功能,一些算法將委託給專用版本。這可以在一定程度上減少代碼的減少,但通過爲迭代器選擇最適合的算法大大提高效率。

注意,STL是不是在分離完全一致:std::list具有使用實施的具體細節,以自行解決自己的sort成員函數,和std::string具有的成員函數算法,其中大部分可能已經實施了數量巨大作爲非會員功能。