Vector of templated vectors

Viewed 473

I want to create a vector of vectors, where the individual vectors can be of different types, as follows:

std::vector<int> v1;
std::vector<float> v2;
std::vector<double> v3;

std::vector<SomeType> all;
all.push_back(v1);
all.push_back(v2);
all.push_back(v3);

What should SomeType be in this case?

My actual use case:

I have vectors of different data types which need to be written out to disk. Everytime I add a column to the dataset, I don't want to have to specify the column in various different places. I want to be able to iterate through the columns easily.

2 Answers

There are a lot of ways to do this, depending on your situation. Here's a variant (pun) with std::variant:

std::vector<int> v1 = { 1, 2, 3 };
std::vector<float> v2 = { 4.5f, 5.5f, 6.5f };
std::vector<double> v3 = { 7.5, 8.5, 9.5 };

std::vector<std::variant<std::vector<int>, std::vector<float>, std::vector<double>>> all;
all.push_back(v1);
all.push_back(v2);
all.push_back(v3);

for(auto& variant : all)
{
    std::visit([](const auto& container) {
        for(auto value : container)
        {
            std::cout << value << '\n';
        }
    }, variant);
}

std::any with type erasure would also work. Or go one level lower, f.i. with std::vector<std::variant<int, float, double>>.

You can't do this because all 3 vector types are different.

You can however, create a non-templated abstract class with the required abstract functions that you need for std::vector then implement it for each vector type.

Something like this:

struct Base
{
      int size() = 0;
};

template <typename T>
struct VectorWrapper : public Base
{
      std::vector<T>* mVector;
      int size() { return mVector.size(); }
};

int main()
{
     std::vector<int> v;
     // initialize vector

     VectorWrapper<int> w;
     w.mVector = &v;

     std::vector<Base*> all;
     all.push_back(&w)

     return 0; 
}
Related