Aracılığıyla paylaş


C++ Standart Kitaplığı Kapsayıcıları

Standart Kitaplık, ilgili nesne koleksiyonlarını depolamak için çeşitli tür güvenli kapsayıcılar sağlar. Kapsayıcılar sınıf şablonlarıdır. Bir kapsayıcı değişkeni bildirdiğinizde, kapsayıcının barındıracağı öğelerin türünü belirtirsiniz. Kapsayıcılar başlatıcı listeleriyle oluşturulabilir. Öğeleri ekleyip kaldırmak ve diğer işlemleri yapmak için üye işlevlerine sahiptir.

Kapsayıcıdaki öğeler üzerinde yineleme yapın ve yineleyicileri kullanarak tek tek öğelere erişin. Yineleyicileri, üye işlevlerini ve işleçlerini ve genel işlevlerini kullanarak açıkça kullanabilirsiniz. Bunları örtük olarak da kullanabilirsiniz, örneğin bir range-for döngüsü kullanabilirsiniz. Tüm C++ Standart Kitaplığı kapsayıcıları için yineleyiciler ortak bir arabirime sahiptir ancak her kapsayıcı kendi özel yineleyicilerini tanımlar.

Kapsayıcılar üç kategoriye ayrılabilir: sıralı kapsayıcılar, ilişkilendirilebilir kapsayıcılar ve kapsayıcı bağdaştırıcıları.

Sıralı Kapsayıcılar

Sıra kapsayıcıları, belirttiğiniz eklenen öğelerin sırasını korur.

Kapsayıcı vector bir dizi gibi davranır, ancak gerektiğinde otomatik olarak büyüyebilir. Rastgele erişim ve bitişik olarak depolanır ve uzunluk son derece esnektir. Bu nedenlerle ve daha fazlası, vector çoğu uygulama için tercih edilen sıralı kapsayıcıdır. Ne tür bir dizi kapsayıcısı kullanılacağından şüpheniz olduğunda, bir vektör kullanarak başlayın! Daha fazla bilgi için bkz vector . Sınıf.

Kapsayıcının array bazı güçlü yönleri vectorvardır, ancak uzunluğu o kadar esnek değildir. Daha fazla bilgi için bkz array . Sınıf.

deque (Çift uçlu kuyruk) kapsayıcısı, kapsayıcının başında ve sonunda hızlı ekleme ve silme işlemlerine olanak tanır. rastgele erişim ve esnek uzunluk avantajlarını vectorpaylaşır, ancak bitişik değildir. Daha fazla bilgi için bkz deque . Sınıf.

Kapsayıcı list , kapsayıcının herhangi bir yerinde çift yönlü erişim, hızlı eklemeler ve hızlı silme işlemlerine olanak tanıyan, ancak kapsayıcıdaki bir öğeye rastgele erişemezsiniz. Daha fazla bilgi için bkz list . Sınıf.

Kapsayıcı forward_list tek bağlantılı bir listedir; ileri erişim sürümüdür list. Daha fazla bilgi için bkz forward_list . Sınıf.

İlişkili Kapsayıcılar

İlişkili kapsayıcılarda, öğeler önceden tanımlanmış bir düzende (örneğin artan düzende sıralanmış olarak) eklenir. Sıralanmamış ilişkilendirme kapsayıcıları da kullanılabilir. İlişkili kapsayıcılar iki alt küme halinde gruplandırılabilir: haritalar ve kümeler.

mapBazen sözlük olarak da adlandırılan bir , anahtar/değer çiftlerinden oluşur. Anahtar, sırayı sıralamak için kullanılır ve değer bu anahtarla ilişkilendirilir. Örneğin, bir map metindeki her benzersiz sözcüğü temsil eden anahtarlar ve her sözcüğün metinde görünme sayısını temsil eden karşılık gelen değerler içerebilir. 'un map sıralanmamış sürümüdür unordered_map. Daha fazla bilgi için bkz map . Sınıf ve unordered_map Sınıf.

A set yalnızca benzersiz öğelerden oluşan artan bir kapsayıcıdır; değer aynı zamanda anahtardır. 'un set sıralanmamış sürümüdür unordered_set. Daha fazla bilgi için bkz set . Sınıf ve unordered_set Sınıf.

set Hem hem de map yalnızca bir anahtar veya öğenin kapsayıcıya eklenmesine izin verir. Birden çok öğe örneği gerekiyorsa veya multisetkullanınmultimap. Sıralanmamış sürümler ve unordered_multisetşeklindedirunordered_multimap. Daha fazla bilgi için bkz multimap . Sınıf, unordered_multimap Sınıf, multiset Sınıf ve unordered_multiset Sınıf.

Sıralı haritalar ve kümeler çift yönlü yineleyicileri, sıralanmamış karşılıkları ise ileriye doğru yineleyicileri destekler. Daha fazla bilgi için bkz . Yineleyiciler.

İlişkili Kapsayıcılarda Heterojen Arama (C++14)

Sıralı ilişkilendirici kapsayıcılar (eşleme, çoklu harita, küme ve çok kümeli) artık heterojen aramayı destekliyor, yani artık ve lower_bound()gibi find() üye işlevlerinde anahtar veya öğeyle tam olarak aynı nesne türünü geçirmeniz gerekmiyor. Bunun yerine, anahtar türüyle karşılaştırmayı etkinleştiren aşırı yüklenmiş operator< bir türün tanımlandığı herhangi bir türü geçirebilirsiniz.

Kapsayıcı değişkenini bildirirken veya std::greater<> "elmas funktör" karşılaştırıcısını std::less<> belirttiğinizde heterojen arama, burada gösterildiği gibi kabul temelinde etkinleştirilir:

std::set<BigObject, std::less<>> myNewSet;

Varsayılan karşılaştırıcıyı kullanırsanız, kapsayıcı tam olarak C++11 ve önceki sürümlerde olduğu gibi davranır.

Aşağıdaki örnekte, her nesnenin üyesiyle karşılaştırılabilir küçük bir std::set dize geçirerek kullanıcılarının arama yapmasını sağlamak için nasıl aşırı yükleyebileceğiniz operator< gösterilmektedirBigObject::id.

#include <set>
#include <string>
#include <iostream>
#include <functional>

using namespace std;

class BigObject
{
public:
    string id;
    explicit BigObject(const string& s) : id(s) {}
    bool operator< (const BigObject& other) const
    {
        return this->id < other.id;
    }

    // Other members....
};

inline bool operator<(const string& otherId, const BigObject& obj)
{
    return otherId < obj.id;
}

inline bool operator<(const BigObject& obj, const string& otherId)
{
    return obj.id < otherId;
}

int main()
{
    // Use C++14 brace-init syntax to invoke BigObject(string).
    // The s suffix invokes string ctor. It is a C++14 user-defined
    // literal defined in <string>
    BigObject b1{ "42F"s };
    BigObject b2{ "52F"s };
    BigObject b3{ "62F"s };
    set<BigObject, less<>> myNewSet; // C++14
    myNewSet.insert(b1);
    myNewSet.insert(b2);
    myNewSet.insert(b3);
    auto it = myNewSet.find(string("62F"));
    if (it != myNewSet.end())
        cout << "myNewSet element = " << it->id << endl;
    else
        cout << "element not found " << endl;

    // Keep console open in debug mode:
    cout << endl << "Press Enter to exit.";
    string s;
    getline(cin, s);
    return 0;
}

//Output: myNewSet element = 62F

Eşlem, çoklu harita, küme ve çok kümeli aşağıdaki üye işlevleri heterojen aramayı desteklemek için aşırı yüklenmiştir:

  1. find

  2. count

  3. lower_bound

  4. upper_bound

  5. equal_range

Kapsayıcı Bağdaştırıcıları

Kapsayıcı bağdaştırıcısı, arabirimi basitlik ve netlik açısından kısıtlayan bir dizi veya ilişkilendirici kapsayıcının çeşitlemesidir. Kapsayıcı bağdaştırıcıları yineleyicileri desteklemez.

Kapsayıcı queue FIFO (ilk gelen, ilk çıkan) semantiğini izler. Kuyruğa gönderilen ilk öğe ,yani kuyruğa eklenen ilk öğedir; yani kuyruktan kaldırılan ilk öğedir. Daha fazla bilgi için bkz queue . Sınıf.

Kapsayıcı priority_queue , en yüksek değere sahip öğe her zaman kuyrukta ilk sırada olacak şekilde düzenlenir. Daha fazla bilgi için bkz priority_queue . Sınıf.

Kapsayıcı stack , LIFO (last in, first out) semantiğini izler. Yığına gönderilen son öğe, ilk atılan öğedir. Daha fazla bilgi için bkz stack . Sınıf.

Kapsayıcı bağdaştırıcıları yineleyicileri desteklemediğinden, C++ Standart Kitaplık algoritmalarıyla kullanılamaz. Daha fazla bilgi için bkz . Algoritmalar.

Kapsayıcı Öğeleri gereksinimleri

Genel olarak, C++ Standart Kitaplığı kapsayıcısına eklenen öğeler, kopyalanabilir olmaları durumunda hemen hemen herhangi bir nesne türünde olabilir. Yalnızca taşınabilir öğeler; örneğin, kullanılarak unique_ptr<> oluşturulanlar, vector<unique_ptr<T>> bunları kopyalamaya çalışan üye işlevlerini çağırmadığınız sürece çalışır.

Yıkıcının özel durum oluşturmasına izin verilmez.

Bu makalenin önceki bölümlerinde açıklanan sıralı ilişkilendirici kapsayıcıların tanımlanmış bir genel karşılaştırma işleci olmalıdır. Varsayılan olarak işleç şeklindedir operator<, ancak birlikte operator< çalışmayan türler bile desteklenir.

Kapsayıcılardaki bazı işlemler için ortak varsayılan oluşturucu ve genel eşdeğerlik işleci de gerekebilir. Örneğin, sıralanmamış ilişkilendirme kapsayıcıları eşitlik ve karma için destek gerektirir.

Kapsayıcı Öğelerine Erişme

Kapsayıcıların öğelerine yineleyiciler kullanılarak erişilir. Daha fazla bilgi için bkz . Yineleyiciler.

Dekont

C++ Standart Kitaplık koleksiyonlarını yinelemek için aralık tabanlı for döngülerini de kullanabilirsiniz.

Kapsayıcıları karşılaştırma

Tüm kapsayıcılar, aynı öğe türüne sahip aynı türde iki kapsayıcıyı karşılaştırmak için operator== öğesini aşırı yükler. Bir vektör dizesini başka bir vektör<>< dizesiyle> karşılaştırmak için == kullanabilirsiniz, ancak bunu kullanarak bir vektör<dizesini liste<dizesiyle> veya vektör<dizesini>> vektör<karakteriyle*> karşılaştıramazsınız. C++98/03'te, farklı kapsayıcı türlerini ve/veya öğe türlerini karşılaştırmak için veya std::mismatch kullanabilirsinizstd::equal. C++11'de de kullanabilirsiniz std::is_permutation. Ancak tüm bu durumlarda işlevler kapsayıcıların aynı uzunlukta olduğunu varsayar. İkinci aralık ilkinden daha kısaysa tanımsız davranış sonuçları elde edilir. İkinci aralık daha uzunsa, karşılaştırma ilk aralığın sonunu asla geçemediğinden sonuçlar yine de yanlış olabilir.

Benzersiz kapsayıcıları karşılaştırma (C++14)

C++14 ve sonraki sürümlerde, iki tam aralığı alan , std::mismatchveya işlev aşırı yüklemelerinden std::equalbirini kullanarak benzer olmayan kapsayıcıları ve/veya std::is_permutation benzer olmayan öğe türlerini karşılaştırabilirsiniz. Bu aşırı yüklemeler, farklı uzunluklara sahip kapsayıcıları karşılaştırmanıza olanak tanır. Bu aşırı yüklemeler kullanıcı hatasına çok daha az duyarlıdır ve farklı uzunluktaki kapsayıcılar karşılaştırıldığında sabit süre içinde false döndürecek şekilde iyileştirilir. Bu nedenle, bunu yapmak için net bir nedeniniz yoksa veya çift aralıklı iyileştirmelerden yararlanmayan bir std::list kapsayıcı kullanmadığınız sürece bu aşırı yüklemeleri kullanmanızı öneririz.

Ayrıca bkz.

Paralel Kapsayıcılar
<sample container>
C++ Standart Kitaplığında İş Parçacığı Güvenliği