Humam Helfawi Humam Helfawi - 1 month ago 9
C++ Question

Initialize vector of vectors with reserved vector

I have a vector of vectors:

std::vector<std::vector<T>> v;


I want to initialize this vector with 5 items(5 vectors of T). Each one of those vectors will contain between 0 and 10 items. Obviously, I need the inner vectors to be reserved with 10 rather than sized with 10. I do not need unnecessary reallocation or copies to happen. In other words, I need emplace-construction.

Since
std::vector
does not provide a constructor with the needed number of items to reserve, I came up with this idea:

std::vector<std::vector<T>> v(5,
[](){
std::vector<T> temp;
temp.reserve(10);
return temp;
}());


Questions:


  1. Is it valid? Does this contain an undefined behavior?

  2. Did I really minimize the resources needed to do what I described above? I feel like there are unnecessary copies in my approach.


Answer
  1. Not invalid, but it doesn't do what you want. As far as I can tell, there is no undefined behavior here.
  2. There may be one unnecessary copy if the optimizer performs badly.

That being said, you're not doing what you set out to do at all. If you check the capacity() of v's elements, you'll see that they're not set to 10. That's because vector's copy constructor is not defined to copy the container verbatim - it copies its elements.

To do what you wanted you need to call reserve() after those vectors have been constructed:

std::vector<std::vector<T>> v(5);
for(auto& vec : v) {
    vec.reserve(10);
}

It has the added benefit of being less code and more readable.