Search code examples
c++vectormodeling

C++ structure, similar to vector but which resizes automatically


I'm coding a simulation of spatial cell growth in a "corridor". I start with a certain number of cells in a line (i.e. the "width" of my corridor) and let them grow in a stochastical fashion downwards along the "length" of the corridor. Because I need to be able to access all the cells via their coordinates on my corridor, I always used a 2d vector (i.e. a vector whose elements are vectors again) grid and saved my cells in there.

My problem now is that with my current simulation I don't know how far my cells need to grow along the corridor, i.e. I don't know the "length" I need for my 2d grid. (Because this will vary stochastically from run to run) In order to "grow" my cells i.e. place new objects onto my grid, I need to access specific grid points though, but if I don't know the max. length required yet I can't initiate a vector with sufficient length at the beginning.

Is there some kind of structure where I can access each slot via an index, just like in vector, but where I don't need to set out from the start how big it is? (I know with vector I don't need to specify the length right from the start, but I don't always use append, becauae sometimes there are gaps in the grid so I need to have access to specific indeces right from the start).

I'm sorry if I formulated the question not clear enough, please let me know if you have an idea or if the question is unclear. Thank you!


Solution

  • You could write something along the line of:

    #include <vector>
    #include <iostream>
    
    struct foo { 
        std::vector<int> data;
        int& operator[](size_t i){
            if ( data.size() < i) data.resize(i-1);
            return data[i];
        }
    };
    
    int main() {
        foo f;
        f[100] = 10;
        std::cout << f[100];
    }
    

    However, I would not advise to actually use that. std::vector gives you fine grained control about when and where allocations happen. You can use resize and/or reserve to make sure the vector has enough elements / capacity. On the other hand, the above will cause you to resize the vector in places where one would not expect it. push_back is to add elements, while accessing an element via [] or at should either access an element or fail.

    What you can do instead is reserve enough space and then push_back as many element you will have:

     std::vector<int> foo;
     // dont know how many elements exactly, but it will be less than 1000
     foo.reserve(1000);
     while (some_condition()) foo.push_back(something());