2012-08-14 12 views
8

Nie mogę zrozumieć, dlaczego rozdzielili algorytmy, iteratory i kontenery w C++ STL. Jeśli wszędzie używasz szablonów, możemy mieć klasy zawierające wszystkie rzeczy w jednym miejscu z parametrami szablonu.Dlaczego istnieje rozdział algorytmów, iteratorów i kontenerów w C++ STL

tekst, który wyjaśnia, że ​​mam iteratory pomaga algorytmów do interakcji z danymi pojemniki ale co jeśli pojemniki wystawiać jakiś mechanizm dostępu do danych to posiadającą?

+1

Nie rozumiem słowa, które napisałeś. :( – Mehrdad

+0

OK przepraszam za zamieszanie, co mam na myśli, mamy różne klasy dla kontenerów, iteratorów itp. Chcę dowiedzieć się, co jest nie tak, jeśli umieścimy wszystkie w jednej klasie przy użyciu szablonów, kontenery mają dane i mogą odsłonić niektóre interfejsy, aby zobaczyć lub zmodyfikuj, dlaczego są oddzielne? Mam na myśli, dlaczego istnieją różne iteratory, algorytmy itp. – Rahul

+3

[To pytanie] (http://stackoverflow.com/questions/10380612/principles-behind-stl-design) może dać ci trochę Wskaźniki [Ten wywiad] (http://www.sgi.com/tech/stl/drdobbs-interview.html) z Alexem Stiepanowem, twórcą STL, zawiera także kilka spostrzeżeń: –

Odpowiedz

22

Z M pojemnikach + N algorytmów, można by normalnie trzeba M * N kawałki kodu, ale z iteratorów działających jako „klej”, to może być zredukowana do M + N kawałków kodu.

przykład: run 2 algorytmy na 3 pojemnikach

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); 

Telefonujesz tylko 2 różne algorytmy i tylko kod dla 3 pojemników. Każdy pojemnik przekazuje do kontenerów iteratory begin() i end(). Mimo, że masz 3 * 2 linii kodu do generowania odpowiedzi, istnieje tylko 3 + 2 funkcji, które należy zapisać.

W przypadku większej liczby pojemników i algorytmów separacja ta stanowi olbrzymią redukcję w kombinatorycznej eksplozji kodu, która w przeciwnym razie byłaby następstwem: w STL jest 5 kontenerów sekwencji, 8 kontenerów asocjacyjnych i 3 adaptery kontenerów, a jest ich prawie 80 algorytmów w <algorithm> sam (nawet nie licząc tych w <numeric>), tak, że masz tylko 16 + 80 zamiast 16 * 80 An 13-krotne zmniejszenie w kodzie! (Oczywiście nie każdy algorytm ma sens na każdym kontenerze, ale punkt powinien być jasny).

Iteratory można podzielić na 5 kategorii (wejściowe, wyjściowe, do przodu, dwukierunkowe i losowe), a niektóre algorytmy będą delegować do wersji specjalistycznych w zależności od możliwości iteratora. To zmniejszy nieco redukcję kodu, ale znacznie poprawi wydajność, wybierając najlepiej dostosowany algorytm do iteratora pod ręką.

Zauważ, że STL nie jest całkowicie zgodny w separacji: std::list ma swoją własną funkcję sort członka, który wykorzystuje specyficzne szczegóły implementacji do sortowania się i std::string posiada ogromną liczbę algorytmów funkcji składowej, z których większość mogły być realizowane jako funkcje nie będące członkami.

Powiązane problemy