![[Dept of Engineering]](http://www.eng.cam.ac.uk/images/house_style/engban-s.gif)
vector doesn't have range-checking by default, but if you
use the member function vector::at(), out_of_range
exceptions can be trapped, so you can add
out_of_range checking by redefining [ ] in a class
derived from vector, and using vector's constructors -
template<class T> class Vec: public vector<T> {
public:
Vec() : vector<T>() {}
Vec(int s) : vector<T>(s) {}
T& operator[] (int i) {return at(i);}
const T& operator[] (int i) const {return at(i);}
}
The following more complicated example creates a mapping (relating a string to a number) without using the Standard Library's map facility. It does a word-frequency count of the text given to it.
[fontsize=\small,frame=single,formatcom=\color{progcolor}]
#include <iostream>
#include <string>
#include <vector>
using namespace std;
// The Assoc class contains a vector of string-int Pairs.
class Assoc {
struct Pair {
string name;
int val;
// The following line is a constructor for Pair
Pair (string n="", int v=0): name(n), val(v) {}
};
// create a vector of the Pairs we've just created
vector <Pair> vec;
public:
// redefine []
int& operator[] (const string&);
// a member function to print the vector out
void print_all() const;
};
// This redefines [] so that a ref to the value corresponding to the
// string is returned if it exists. If it doesn't exist, an entry
// is created and the value returned.
int& Assoc::operator[] (const string& s)
{
// The next line's creating an appropriate iterator
// for the vector of Pairs
for (vector<Pair>::iterator p=vec.begin(); p!=vec.end(); ++p)
if (s == p->name)
return p->val;
vec.push_back(Pair(s,0));
return vec.back().val;
}
void Assoc::print_all() const
{
for(vector<Pair>::const_iterator p=vec.begin(); p!=vec.end(); ++p)
cout << p->name<<": " << p->val << endl;
}
int main()
{
string buf;
Assoc vec;
cout << "Type in some strings then press CTRL-D to end input\n";
while(cin>>buf) vec[buf]++;
vec.print_all();
}