'C++ template implementation to store 2D nested vector data continuously?

Storing a two-dimensional grid as std::vector<std::vector<double>> is rather inefficient because each of the inner vectors contains separately allocated heap memory. I am seeking a template implementation to let me do the things like:

nested_vector<double, 2> nv;
nv.push_back({0, 1, 2});   // row1
nv.push_back({3, 4});      // row2
nv.push_back({5, 6, 7, 8});// row3

Ideal storage in memory:

-------------------------------------------------
|     row 1     |     row 2     |     row 3     |
-------------------------------------------------

instead of

std::vector<std::vector<double>>  v = {{0, 1, 2}, {3, 4}, {5, 6, 7, 8}};
--------------
|     row 1     |
-------------
|     row 2     |
-------------
|     row 3     |
--------------


Is there any template implementation to do this? Any tips will be appreciated, thanks in advance.



Solution 1:[1]

You do not need a template to pass different number of parameters to a function. You can use a initializer list:

#include <iostream>
#include <vector>

using namespace std;

struct foo {
    std::vector<int> data;
    void add(std::initializer_list<int> a){
        std::copy(a.begin(),a.end(),std::back_inserter(data));
    }
};

int main() 
{
    foo f;
    f.add({1,2,3});
    f.add({1,2,3,4});
    f.add({1,2,3,4,5});
    for (const auto& e : f.data) std::cout << e;
}

However, as the "rows" are of different size, you will need to do more to know where a row ends. If row sizes are dynamic and can change during runtime then a std::vector<std::vector<int>> is probably just fine. Using a flat 1d container and resizing rows would require to move around elements very often. Also you cannot resize when you do not know the size of a row before hand. Things are different when the size of the rows is fixed, then you'd need to do the index transformations and place added elements at the right position.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 463035818_is_not_a_number