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 vector
vardı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ı vector
paylaşı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.
map
Bazen 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 multiset
kullanı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:
find
count
lower_bound
upper_bound
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.
Not
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::mismatch
veya işlev aşırı yüklemelerinden std::equal
birini 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