Using a template, the following example shows the operations
supported by all the basic sequences: vector, deque, and list:
//: C07:BasicSequenceOperations.cpp
// The operations available for all the
// basic sequence Containers.
#include <deque>
#include <iostream>
#include <list>
#include <vector>
using namespace std;
template<typename Container>
void print(Container& c, char* title =
"") {
cout << title << ':' << endl;
if(c.empty()) {
cout << "(empty)" << endl;
return;
}
typename Container::iterator it;
for(it = c.begin(); it != c.end(); it++)
cout << *it << " ";
cout << endl;
cout << "size() " <<
c.size()
<< " max_size() " <<
c.max_size()
<< " front() " <<
c.front()
<< " back() " <<
c.back()
<< endl;
}
template<typename ContainerOfInt> void
basicOps(char* s) {
cout << "------- " << s
<< " -------" << endl;
typedef ContainerOfInt Ci;
Ci c;
print(c, "c after default constructor");
Ci c2(10, 1); // 10 elements, values all 1
print(c2, "c2 after constructor(10,1)");
int ia[] = { 1, 3, 5, 7, 9 };
const int IASZ = sizeof(ia)/sizeof(*ia);
// Initialize with begin & end iterators:
Ci c3(ia, ia + IASZ);
print(c3, "c3 after
constructor(iter,iter)");
Ci c4(c2); // Copy-constructor
print(c4, "c4 after copy-constructor(c2)");
c = c2; // Assignment operator
print(c, "c after operator=c2");
c.assign(10, 2); // 10 elements, values all 2
print(c, "c after assign(10, 2)");
// Assign with begin & end iterators:
c.assign(ia, ia + IASZ);
print(c, "c after assign(iter, iter)");
cout << "c using reverse iterators:"
<< endl;
typename Ci::reverse_iterator rit = c.rbegin();
while(rit != c.rend())
cout << *rit++ << " ";
cout << endl;
c.resize(4);
print(c, "c after resize(4)");
c.push_back(47);
print(c, "c after push_back(47)");
c.pop_back();
print(c, "c after pop_back()");
typename Ci::iterator it = c.begin();
++it; ++it;
c.insert(it, 74);
print(c, "c after insert(it, 74)");
it = c.begin();
++it;
c.insert(it, 3, 96);
print(c, "c after insert(it, 3, 96)");
it = c.begin();
++it;
c.insert(it, c3.begin(), c3.end());
print(c, "c after insert("
"it, c3.begin(), c3.end())");
it = c.begin();
++it;
c.erase(it);
print(c, "c after erase(it)");
typename Ci::iterator it2 = it = c.begin();
++it;
++it2; ++it2; ++it2; ++it2; ++it2;
c.erase(it, it2);
print(c, "c after erase(it, it2)");
c.swap(c2);
print(c, "c after swap(c2)");
c.clear();
print(c, "c after clear()");
}
int main() {
basicOps<vector<int>
>("vector");
basicOps<deque<int> >("deque");
basicOps<list<int> >("list");
} ///:~
All the basic sequence containers are reversible containers,
as shown by the use of the rbegin( ) and rend( ) member
functions. A sequence container can be resized, and the entire contents of the
container can be removed with clear( ). When you call resize( ) to expand a sequence, the new elements use the default constructor of the type
of element in the sequence, or if they are built-in types, they are
zero-initialized.
Using an iterator to indicate where you want to start
inserting into any sequence container, you can insert( ) a single element, a number of elements that all have the same value, and a group of
elements from another container using the beginning and ending iterators of
that group.
The following sections discuss the particulars of each type
of sequence container.