CS253: Software Development with C++

Fall 2020

STL Containers

Show Lecture.STLContainers as a slide show.

CS253 STL Containers

Overview

Attributes

NameKey/ValueInsertionAppendSearchOrdered
string, vectorvalueO(n)O(1)O(n)no
list, forward_listvalueO(1)O(1)O(n)no
[multi]setvalueO(log n) O(log n)yes
[multi]mapkey/valueO(log n) O(log n)yes
dequevalueO(n)O(1)O(n)no
unordered_[multi]setvalueO(1) O(1)oddly
unordered_[multi]mapkey/valueO(1) O(1)oddly

Popular methods

Popular types

string

string con = "The quick brown fox jumps over a lazy dog.";
cout << "size=" << con.size() << ' ';
for (auto c : con)
    cout << c;
size=42 The quick brown fox jumps over a lazy dog.

vector

string s = "The quick brown fox jumps over a lazy dog.";
vector<char> con(s.begin(), s.end());
cout << "size=" << con.size() << ' ';
for (auto c : con)
    cout << c;
size=42 The quick brown fox jumps over a lazy dog.

We can’t initialize a vector directly from a C-style string, so we put it into a C++ string, and initialize the vector from that, using the two-iterator constructor.

array

string s = "The quick brown fox jumps over a lazy dog.";
array<char, 41> con;
for (size_t i=0; i<s.size(); i++)
    con[i] = s[i];
cout << "size=" << con.size() << ' ';
for (auto c : con)
    cout << c;
size=41 The quick brown fox jumps over a lazy dog

A std::array is not a C array. However, it does have a size fixed at compile time. Its storage is all on the stack, with no dynamic memory allocation, so it’s as effecient as a C array. It has typical STL container methods such as .size(), .begin(), .end(), etc. It lacks the two-iterator ctor, perhaps due to its fixed size.

list

string s = "The quick brown fox jumps over a lazy dog.";
list<char> con(s.begin(), s.end());
cout << "size=" << con.size() << ' ';
for (auto c : con)
    cout << c;
size=42 The quick brown fox jumps over a lazy dog.

A list is a doubly-linked list. It has a large storage overhead, but insertion is cheap, and you can easily go forward & backward. Unlike a vector, .push_back() never causes reallocation.

forward_list

string s = "The quick brown fox jumps over a lazy dog.";
forward_list<char> con(s.begin(), s.end());
for (auto c : con)
    cout << c;
The quick brown fox jumps over a lazy dog.

A forward_list (formerly slist) is a singly-linked list. It has a large storage overhead, but insertion is cheap, and you can easily go forward. Curiously, there is no forward_list::size().

deque

string s = "The quick brown fox jumps over a lazy dog.";
deque<char> con(s.begin(), s.end());
cout << "size=" << con.size() << ' ';
for (auto c : con)
    cout << c;
size=42 The quick brown fox jumps over a lazy dog.

A deque is a double-ended queue. It’s like a vector, but you can easily push or pop from the front or the back.

set

string s = "The quick brown fox jumps over a lazy dog.";
set<char> con(s.begin(), s.end());
cout << "size=" << con.size() << ' ';
for (auto c : con)
    cout << c;
size=28  .Tabcdefghijklmnopqrsuvwxyz

A set is generally implemented as a binary tree. Hence, it is sorted, has fairly large storage overhead, and has O(log n) find/insertion/deletion times.

multiset

string s = "The quick brown fox jumps over a lazy dog.";
multiset<char> con(s.begin(), s.end());
cout << "size=" << con.size() << ' ';
for (auto c : con)
    cout << c;
size=42         .Taabcdeefghijklmnoooopqrrsuuvwxyz

A multiset is like a set, but allows copies.

unordered_set

string s = "The quick brown fox jumps over a lazy dog.";
unordered_set<char> con(s.begin(), s.end());
cout << "size=" << con.size() << ' ';
for (auto c : con)
    cout << c;
size=28 .gdyzlaspmjxfnworbkciuqv ehT

A unordered_set (formerly hash_set), is a hash table implementation like a set.

unordered_multiset

string s = "The quick brown fox jumps over a lazy dog.";
unordered_multiset<char> con(s.begin(), s.end());
cout << "size=" << con.size() << ' ';
for (auto c : con)
    cout << c;
size=42 .gdyzlaaspmjxfnwoooorrbkciuuqv        eehT

A unordered_multiset (formerly hash_multiset), is a hash table implementation like a multiset.

map, multimap, unordered_map, unordered_multimap

map example

map<string, double> gpa = {
    { "Jack",  3.998 },
    { "Russ",  4.20  },
    { "Wim",   3.92  },
    { "Craig", 2.0   }
};

for (auto p : gpa)
    cout << p.first << " has a GPA of " << p.second << '\n';
cout << "Jack’s GPA is: " << gpa["Jack"] << '\n';
Craig has a GPA of 2
Jack has a GPA of 3.998
Russ has a GPA of 4.2
Wim has a GPA of 3.92
Jack’s GPA is: 3.998