Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reserving sub vectors while constructing

Tags:

c++

c++11

vector

I have this:

size_t n = 100;
std::vector<std::vector<foo>> v(n);

The count of the sub vectors is dynamic but known. However, the number of items in each vector is not known but I have an estimation about it so I want to reserve the sub vectors before start pushing back into them. What I am currently doing is:

size_t estimated_size = 1000;
for (auto& sub_vector: v){
   sub_vector.reserve(estimated_size);
}

Is there a better way? Like doing it while constructing?

P.S. This is not an option:

size_t n = 100;
size_t estimated_size = 1000;
std::vector<std::vector<foo>> v(n, std::vector<foo>(estimated_size));

I just want to reserve without constructing because foo is costy to be constructed twice.

like image 388
Humam Helfawi Avatar asked Mar 01 '16 09:03

Humam Helfawi


1 Answers

If you really want to do it while constructing the vector you could use the constructor that takes two iterators and provide your own custom iterator. Dereferencing the iterator would create a vector reserve it and then return it:

class VectorReserveItr : public std::iterator<std::input_iterator_tag, foo> {
  size_t i;
  size_t capacity;
public:
  VectorReserveItr(size_t i, size_t capacity) : i(i), capacity(capacity) {}
  VectorReserveItr& operator++() { ++i; return *this; }
  bool operator!=(const VectorReserveItr& rhs) { return i != rhs.i; }
  std::vector<foo> operator*() {
      std::vector<foo> ret;
      ret.reserve(capacity);
      return ret;
  }
};

std::vector<std::vector<foo>> v(VectorReserveItr(0, 1000), VectorReserveItr(100, 1000));

But I wouldn't expect it to be faster than a loop and I don't think it is more readable either.

Live demo.

like image 134
user3467895 Avatar answered Sep 24 '22 03:09

user3467895