Search code examples
c++classc++11stdvectorstdinitializerlist

How to use initialiser list in constructor call to configure `std::vector<std::vector<MyClass>>`?


About an hour ago or so, I have been pointed out to something called initializer list, so immediately I have started researching it, but there is one thing I cannot understand.

If I have something like:

class ExtClass {
    public:
        int ext;
        int pet;        
        ExtClass();
};

ExtClass::ExtClass() {
    this->ext = rand();
    this->pet = rand();
}

class MainClass {
    public:    
        std::vector<std::vector<ExtClass>> attribute;

        MainClass(std::vector<int>>);
};

MainClass::MainClass(std::vector<int> varName) : attribute(...) { }

The thing is I want this to happen:

attribute[0] has {1, 2, 3, 4} of type ExtClass
attribute[1] has {5, 6}       of type ExtClass
attribute[2] has {7, 8, 9}    of type ExtClass

and so on.

What I would like is when I call:

std::vector<int> a{4, 2, 3};
MainClass mainObject(a);

to get the example I have written:

attribute[0] reserves 4 places and creates 4 objects using ExtClass constructor
attribute[1] reserves 2 places and creates 2 objects using ExtClass constructor
attribute[2] reserves 3 places and creates 3 objects using ExtClass constructor

Is there any short way to do that with initializer list or do I need to take another approach (if so which)?


Solution

  • You can std::vector::resize each vector of std::vector<ExtClass> in the constrotr of the MainClass.

    See a (sample code)

    MainClass(const std::vector<int>& vec)
        : attribute(vec.size())
    {
        int row = 0;
        // each cols will be resized to as per
        for(const int colSize: vec) attribute[row++].resize(colSize);
    }
    

    Or as @RSahu suggested in in the comments.

    MainClass(const std::vector<int>& vec)
    {
        attribute.reserve(vec.size()); // reserve the memory for row = vec.size()
        for (const int colSize : vec)
            attribute.emplace_back(std::vector<ExtClass>(colSize));
    }