The STL container class template vector<T> can be taken as a guide for how to do containers. We're going to look at some examples to review some of the vector<T> basics, and introduce some new fundamentals at the same time. Including an output stream iterator.
#include<iostream>
#include<algorithm>
#include<vector>
#include<string>
#include<iterator> // needed for ostream iterator
using namespace std;
int main()
{
// create empty vector container for strings
vector<string> sentence;
// reserve memory for five elements to avoid reallocation
sentence.reserve(5);
// append some elements
sentence.push_back("STL");
sentence.push_back("C++");
sentence.push_back("tutorial");
sentence.push_back("reference");
sentence.push_back("guide");
// print elements separated with spaces
for( int i=0; i<sentence.size(); ++i )
cout<<sentence[i]<< " ";
cout << endl;
// print properties
cout << "max_size(): " << sentence.max_size() << endl;
cout << "size(): " << sentence.size() << endl;
cout << "capacity(): " << sentence.capcity() << endl;
// swap the first and second elements of the vector
swap (sentence[0], sentence[1]);
// insert a word "and" before the word "reference"
vector<string>::iterator insIt = find(sentence.begin(),sentence.end(),"reference");
if (insIt != sentence.end()) // if found
sentence.insert( insIt, "and" ); // insert a word
sentence.push_back(".");
// print elements separated with spaces
ostream_iterator<string> outIt( cout," " );
copy( sentence.begin(), sentence.end(), outIt );
cout << endl;
// print properties
cout << "max_size(): " << sentence.max_size() << endl;
cout << "size(): " << sentence.size() << endl;
cout << "capacity(): " << sentence.capcity() << endl;
}
No visible output loop, it’s in the copy algorithm which takes a stream iterator, called outIt here.
As with other containers, vector<T> is a class template:
template <class T, class Allocator = allocator<T> >
class vector {
//...
}
... where T is the type of data being stored and Allocator specifies an allocator used to implement a dynamic memory allocation strategy for the container.
There are a fair few options, listed without the allocator here. Default, with an empty vector.
vector<int> v0;
Initialisation with values:
vector<int> v1(10, -1); // 10 ints set to -1
Initialisation without values:
vector<int> v2(10); // 10 ints, default set to 0.
By copying from another suitable vector<T>
vector<int> v3(v2);
vector<int> v4=v2; // equiv. to above
Iterator based construction:
vector<int> v5(v4.begin(),v4.end());
List initialisation, from C++11.
vector<string> words = {"one", "two", "red", "blue"};
vector<int> numbers{1, 2, 3, 4, 5, 6, 7};
The elements of a vector can be vectors themselves. A special notation was needed, the addition of a space between the last >,
vector<vector<int> > v6;
... but isn’t from C++11...
vector<vector<int>> v6;
vector<vector<vector<vector<vector<int>>>>> v7;
This was also true for some other composites.
The usual comparison operators:
== (equivalence)
< (less than)
<= (less than or equal to)
> (greater than)
>= (great than or equal to)
!= (not equal to)
But to store something in a vector we need to have: a default constructor, assignment operator (=), equivalent operator (==) and less then operator (<).
Pushing and popping
void push_back(const T& x);
void push_front(const T& x); // for deque
void pop_back();
void pop_front(); // for deque
The use of pop removes an element but doesn’t free the associated memory. We also saw the use of insert earlier.