2012-08-14 12 views
8

'da algoritmaların, yineleyicilerin ve kapsayıcıların bir ayrımı var, neden C++ STL'de algoritmaları, yineleyicileri ve kapsayıcıları ayırdıklarını anlayamıyorum. Eğer her yerde yoğun bir şablon kullanılıyorsa, o zaman her şeyi tek bir yerde şablon parametrelerine sahip sınıflarımız olabilir.Neden C++ STL

Elime aldığım bazı metinler, yineleyicilerin algoritmaların kapsayıcı verileriyle etkileşime girmesine yardımcı olduğunu, ancak kapsayıcının sahip olduğu verilere erişmek için bazı mekanizmalar açığa çıkardığını açıklar. + N algoritmaları M konteyner ile

+1

Yazdığınız bir kelimeyi anlamadım. :( – Mehrdad

+0

Kafam karışıklığı için özür dilerim, ne demek istediğim kapsayıcılar, yineleyiciler vb. Için farklı sınıflarımız var. Şablonları kullanarak hepsini bir sınıfa koyarsak, kapların verileri var ve görmek için bazı arayüzleri açığa çıkarabilirler. Neden ya da değiştirelim, neden ayrı olduklar? Neden farklı yineleyici, algoritma vb. var demektir? – Rahul

+3

[Bu soru] (http://stackoverflow.com/questions/10380612/principles-behind-stl-design) size biraz verebilir. [Bu röportaj] (http://www.sgi.com/tech/stl/drdobbs-interview.html), STL'nin yaratıcısı Alex Stephanov ile birlikte bazı bilgiler içeriyor. –

cevap

22

, bir normal kod M * N parçaları gerekir, ancak "yapıştırıcı" olarak hareket eden adım adım elde, bu kodun M + N parçalara azaltılabilir.

Örnek: run 2 3 konteynerlerin

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

Yalnızca 2 farklı algoritmalar aradığınız üzerine algoritmalar ve sadece 3 konteynerler için kod var. Her kapsayıcı, kapsayıcıya begin() ve end() yineleyicilerini geçirir. Cevapları üretmek için 3 * 2 kod satırınız olsa bile, yazılması gereken yalnızca 3 + 2 adet işlevsellik vardır.

Daha fazla kapsayıcı ve algoritma için, bu ayırma, aksi takdirde kodun oluşturduğu kodlamada meydana gelen patlamada büyük bir azalmadır: STL'de 5 sıra kapsayıcı, 8 ilişkisel kap ve 3 kapsayıcı bağdaştırıcısı vardır ve neredeyse 80 algoritma vardır. <algorithm> tek başına (<numeric> içinde sayma bile) 16 + 80 yerine 16 * 80, kodda 13 kat azalma! (Tabii ki, her algoritma her kapsayıcıda anlam ifade etmiyor, ama nokta açık olmalı).

Yineleyiciler 5 kategoriye ayrılabilir (giriş, çıkış, iletme, çift yönlü ve rasgele erişim) ve bazı algoritmalar yineleyici özelliklerine bağlı olarak özelleştirilmiş sürümlere temsil eder. Bu, kod azaltımını biraz azaltacak, ancak eldeki yineleyiciye en iyi uyarlanmış algoritmayı seçerek verimliliği büyük ölçüde artıracaktır. STL ayrılık tamamen tutarlı değil

Not: std::list kendini sıralamak için uygulama belirli ayrıntıları kullanır kendi sort üye işlevi vardır ve std::string hayata olabilirdi çoğu üye fonksiyonu algoritmaları, muazzam bir numarası vardır üye olmayan işlevler olarak.