Suppose T
is a type, and I want to make a vector<vector<T>>
. I know the eventual size will be m x n
, where m
and n
are runtime constants. (If they were compile-time constants I'd use std::array<std::array<T, n>, m>
.) Suppose I have three choices of what to do with my double vector before I continue with my program in earnest:
Option 1
std::vector<std::vector<T>> dbl_vect(m);
for (auto & v : dbl_vect)
v.reserve(n);
Option 2
std::vector<std::vector<T>> dbl_vect;
dbl_vect.reserve(m);
Option 3
std::vector<std::vector<T>> dbl_vect;
Let's suppose I am not worried about iterator & reference invalidation from vector reallocation, so we can remove that from the decision process.
Of course the code that follows these would have to be a little different, since #1 creates the (empty) rows of the dbl_vector, so we have to access the rows rather than pushing more back.
Option #2 seems fairly useless, because it has no idea how much space to reserve for each row.
Option #1 requires me to go through a linear pass of m
empty vectors and resize them manually, but it prevents reallocation. If T
were pretty big, this would almost certainly be preferable, I believe, because it would prevent copies/moves.
Question: Suppose T = char
(or pick your favorite POD type). Under what circumstances should I be indifferent between options 1 and 3, or even prefer #3? Is this mostly due to the relatively small size of a char
, or because of the way the compiler will (not) default-initialize a char
? If T
is larger, maybe user-defined, at what point (in size of the double vector or in size of T
) should I start caring?
Here a somewhat similar question is asked, regarding one vector and T=int
.