Please do not use nested vectors if the size of your storage is known in advance, i.e. there is a specific reason why, for example, the first index should be 6 and will never change. Just use a simple array. Even better, use boost::array . Thus, you get all the benefits of having a simple array (saving a huge amount of space when you go multi-dimensional), and the benefits of having a real instance of the object.
- Do not use nested vectors if your repository should be rectangular, i.e. you can resize one or more parameters, but each "line" should have the same length at some point. Use
boost::multi_array . Thus, you document "this storage is rectangular", save a huge space and still get the opportunity to change the size, the benefits of having a real object, etc.
The thing about std::vector is that it (a) is designed to resize and (b) does not care about its contents in the least if they are of the correct type. This means that if you have vector<vector<int> > , then all βrow vectorsβ must keep their own separate accounting information about how long they are, even if you want to ensure that they are the same length . It also means that they all manage separate memory allocations, which degrades performance (cache behavior) and consumes even more space due to the way std::vector reallocates. boost::multi_array designed to allow you to resize it, but you will not constantly resize it by adding elements (strings, for a two-dimensional array / faces, for a 3-dimensional array / etc.) to the end. std::vector intended for (potentially) waste, to make sure that the work is not slow. boost::multi_array designed to save space and keep memory neat.
It is said :
Yes, you need to do something before you can index the vector. std::vector will not lead to magical actions for indexes to appear because you want to store something there. However, this is easy to handle:
You can initialize the vector with the desired zeros by default, and then replace them using the constructor (size_t n, const T& value = T()) . I.e
std::vector<int> foo(10);
because the "built by default" int has a value of 0.
In your case, we need to specify the size of each dimension by creating a sub-vector corresponding to the size and allowing the designer to copy them. It looks like this:
typedef vector<float> d1; typedef vector<d1> d2; typedef vector<d2> d3; typedef vector<d3> d4; d4 result(2, d3(7, d2(480, d1(31))));
Thus, an unnamed d1 is created from size 31, which is used to initialize the default d2 , which is used to initialize the default d3 , which is used to initialize the result .
There are other approaches, but they are much clumsy if you just want a bunch of zeros to start. If you are going to read the entire data set from a file, though:
You can use .push_back() to add to a vector. Create an empty d1 just before the inner loop loop in which you re .push_back() to populate it. Right after the loop, you .push_back() result on d2 that you created immediately before the next-inner loop, etc.
You can first resize the vector using .resize() and then index it in the usual way (to the size you resized by).
Karl Knechtel
source share