[Univ of Cambridge] [Dept of Engineering]
next up previous contents
Next: Redefining () Up: More on Classes Previous: copy constructor

Redefining [ ]

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();
}



Tim Love
2001-07-05