title: How Do I define a Double Brackets/Double Iterator Operator, Similar to Vector of Vectors'?
body: <p>I'm porting code that uses a very large array of floats, which may trigger malloc failures from c to c++.  I asked a question about whether I should use vectors or deques and <a href="https://stackoverflow.com/users/117539/niki-yoshiuchi">Niki Yoshiuchi</a> generously offered me this example of a safely wrapped type:</p>
  
  <pre><code>template&lt;typename T&gt;
  class VectorDeque
  {
  private:
    enum TYPE { NONE, DEQUE, VECTOR };
    std::deque&lt;T&gt; m_d;
    std::vector&lt;T&gt; m_v;
    TYPE m_type;
    ...
  public:
    void resize(size_t n)
    {
      switch(m_type)
      {
        case NONE:
        try
        {
          m_v.resize(n);
          m_type = VECTOR;
        }
        catch(std::bad_alloc &amp;ba)
        {
          m_d.resize(n);
          m_type = DEQUE;
        }
        break;
      }
    }
  };
  </code></pre>
  
  <p>I needed a 2D vector of vectors/deque of deques, so I modified it to the following code:</p>
  
  <pre><code>template&lt;typename T&gt;
  class VectorDeque
  {
  private:
    enum STORAGE_CONTAINER { NONE, DEQUE, VECTOR };
    std::deque&lt;std::deque&lt;T&gt; &gt; x_d,y_d,z_d;
    std::vector&lt;std::vector&lt;T&gt; &gt; x_v,y_v,z_v;
    TYPE my_container;
  public:
    void resize(size_t num_atoms, size_t num_frames)
    {
      switch(m_type)
      {
        case NONE:
        try
        {
          x_v.resize(num_atoms);
   for (unsigned int couter=0;couter &lt; num_frames; counter++)
     x_v[counter].resize(num_frames);
          y_v.resize(num_atoms);
   for (unsigned int couter=0;couter &lt; num_frames; counter++)
     y_v[counter].resize(num_frames);
          z_v.resize(num_atoms);
   for (unsigned int couter=0;couter &lt; num_frames; counter++)
     z_v[counter].resize(num_frames);
          my_container = VECTOR;
        }
        catch(std::bad_alloc &amp;e)
        {
          x_d.resize(num_atoms);
   for (unsigned int couter=0;couter &lt; num_frames; counter++)
     x_d[counter].resize(num_frames);
          y_d.resize(num_atoms);
   for (unsigned int couter=0;couter &lt; num_frames; counter++)
     y_d[counter].resize(num_frames);
          z_d.resize(num_atoms);
   for (unsigned int couter=0;couter &lt; num_frames; counter++)
     z_d[counter].resize(num_frames);
          my_container = DEQUE;
        }
        break;
      }
    }
  };
  </code></pre>
  
  <p>I now want to be able to define my bracket operators so that I can have a statement like
  <code>x[1][2]</code> directly access whichever is the <em>real</em> memory container I'm using (given by the value of my enumerated variable.</p>
  
  <p>I've seen a couple of tutorials floating around about overriding the brackets operator, but have positively no idea to override double brackets.</p>
  
  <p>How can you overload double brackets?</p>
  
  <p>Additionally, how would you overload double iterators (in case I want to use an iterator, as opposed to direct indexing)?</p>
  
  <p>EDIT 1: </p>
  
  <p>Based on the solution from Martin York/Matteo Italia I devised the following class:</p>
  
  <pre><code>template&lt;typename T&gt;
  class VectorDeque2D
  {
  public:
  
    class VectorDeque2D_Inner_Set
    {
      VectorDeque2D&amp; parent;
      int   first_index;
    public:
      // Just init the temp object
      VectorDeque2D_Inner_Set(My2D&amp; p, int first_Index) : 
        parent(p), 
        first_Index(first_index) {} 
      // Here we get the value.
      T&amp; operator[](int second_index)  const 
      { return parent.get(first_index,second_index);}   
    };
  
    // Return an object that defines its own operator[] that will access the data.
    // The temp object is very trivial and just allows access to the data via 
    // operator[]
    VectorDeque2D_Inner_Set operator[](unsigned int first_index) { 
      return (*this, x);
    }
  
  
    void resize_first_index(unsigned int first_index) {
      try {
        my_vector.resize(first_index);
        my_container = VECTOR;
      }
      catch(std::bad_alloc &amp;e) {
        my_deque.resize(first_index);
        my_container = DEQUE;
      }
    }
  
    void resize_second_index(unsigned int second_index) {
      try {
        for (unsigned int couter=0;couter &lt; my_vector.size(); counter++) {
      my_vector[counter].resize(second_index);
        }
        my_container = VECTOR;
      }
      catch(std::bad_alloc &amp;e) {
        for (unsigned int couter=0;couter &lt; my_deque.size(); counter++) {
      my_deque[counter].resize(second_index);
        }
        my_container = DEQUE;
      }
    }
    void resize(unsigned int first_index,
            unsigned int second_index) {
      try {
        my_vector.resize(first_index);
        for (unsigned int couter=0;couter &lt; my_vector.size(); counter++) {
      my_vector[counter].resize(second_index);
        }
        my_container = VECTOR;
      }
      catch(std::bad_alloc &amp;e) {
        my_deque.resize(first_index);
        for (unsigned int couter=0;couter &lt; my_deque.size(); counter++) {
      my_deque[counter].resize(second_index);
        }
        my_container = DEQUE;
      }    
    }
  private:
    enum STORAGE_CONTAINER { NONE, DEQUE, VECTOR };
  
    friend class VectorDeque2D_Inner_Set;
  
    std::vector&lt;std::vector&lt;T&gt; &gt; my_vector;
    std::deque&lt;std::deque&lt;T&gt; &gt; my_deque;
    STORAGE_CONTAINER my_container;
  
    T&amp; get(int x,int y) { 
      T temp_val;
      if(my_container == VECTOR) {
        temp_val = my_vector[first_index][second_index];
      }
      else if(my_container == DEQUE) {
        temp_val = my_deque[first_index][second_index];
      }
  
      return temp_val;
    }
  
  };
  </code></pre>
  
  <p>Finally a size-safe 2D container!!  Thanks guys!</p>