From 5544977612968364219
X-Google-Language: ENGLISH,ASCII-7-bit
X-Google-Thread: f78e5,e191db47f821e732
X-Google-Attributes: gidf78e5,public
From: Kresimir Fresl <fresl@grad.hr>
Subject: Re: multidimensional array using stl vector
Date: 1997/07/02
Message-ID: <33B8B20B.7CC8793A@master.grad.hr>#1/1
X-Deja-AN: 254023561
References: <Pine.GSO.3.96.970630204810.3711A-100000@lise.physik.TU-Berlin.DE>
X-Original-Date: Tue, 01 Jul 1997 09:30:19 +0200
Organization: Faculty of Civil Engineering, Zagreb, Croatia
X-Auth: PGPMoose V1.1 PGP comp.std.c++ iQBFAgUBM7oObOEDnX0m9pzZAQEAMgF8CBKrb3vDnbG5hekY59ySwQenmEHLSSyW PHc8wa/n2FU6PqNst1aC137ySdTtORKF =+5sG
Newsgroups: comp.std.c++
Originator: fjh@murlibobo.cs.mu.OZ.AU


Peter Kelm wrote:

> I want to create a two-dimensional array using stl vector
> size is determined at runtime. But how do I do this?
> 
> #include <vector>
> 
> typedef vector<double> row;
> typedef vector<row*>   matrix;
> matrix myMatrix;
> 
> the code above works but if I do it like this i cannot use
> the "common" subscript operator
> 
> myMatrix[1][2] = 5.4;
> 
> Ideas for a simple solution?


My solution (C++ version of 2D arrays in `Numerical Recipes' 
2nd ed. by Press et al.) is: 

  template <typename T>
  class array2d {
  public:
    typedef typename vector<T>::iterator        iterator;
    typedef typename vector<T>::const_iterator  const_iterator;
    typedef typename vector<T>::size_type       size_type;
    
    // ...
    array2d (size_type r, size_type c, T const& val = T())
    : elems (r*c, val), rows (r), nr (r), nc (c) {
      init_rows(); 
    }
    
    iterator operator[] (size_type i) { return rows[i]; }
    const_iterator operator[] (size_type i) const { return rows[i]; }
  
  protected:
    vector<T> elems;         // actual data
    vector<iterator> rows;   // beginnings of rows
    size_type nr;            // number of rows
    size_type nc;            // number of columns
  
    void init_rows() {
      rows[0] = elems.begin();
      for (size_type i = 1; i < nr; ++i)
        rows[i] = rows[i-1] + nc; 
    }
  }; 


In the expression a2d[i][j] first operator[] is
array2d::operator[] which returns vector<T>::iterator 
(lets call it `temp') which `points' to the beginning 
of the ith row. Because vector<T>::iterator is random
access iterator, there must be (according to the CD) 
operator[] defined for it, with operational semantics 
*(temp+j).

Dec. '96 CD says that for random acces iterators 
temp[j] should only have type convertible to T. 
It seems therefore that non-const version of 
array2d::operator[] is not guaranteed to work. But
in a recent post (thread `Questions about iterator 
library') Brian Parker wrote: 

: That's got to be a bug in the draft. The latest SGI version 
: of the STL (at www.sgi.com) specifies that for an iterator x,
: *x returns a type convertible to T to allow for a proxy
: implementation, but also specifies that for mutable iterators
: the dereference assignment expression *x = t is defined 
: (output iterators are an exception). [...]

: I don't know what is on the committee's agenda, but hopefully
: these bugs will be fixed.  

As for current vector implementations, vector<T>::iterator
is simply T* (that is `plain' pointer), and for pointers 
operator[] is defined. 


fres

fresl@grad.hr


PS. All comments on the above code are welcome.
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]



