Akash Agarwal
Akash Agarwal

Reputation: 2520

Add element in single/multiple lists in a vector of list

I've already declared a vector of lists and 3 lists and added those 3 lists in the vector. Now I'd want to add some elements to 2 out of those 3 lists by using the vector only. How can I achieve this?
Here is my code so far:

#include<iostream>
#include<list>
#include<vector>
using namespace std;


#ifndef ILIST
#define ILIST list<int>
#endif

#ifndef VLIST
#define VLIST vector<ILIST >
#endif

int main(int argc, char const *argv[])
{
    ILIST l1(4,10), l2(4,20), l3(4,30);
    VLIST vec;
    vec.push_back(l1);
    vec.push_back(l2);
    vec.push_back(l3);
    //here I want to add 2 elements in l2 and 1 in l3 by using the vector only. 
    return 0;
}

Upvotes: 0

Views: 1847

Answers (1)

kfsone
kfsone

Reputation: 24249

A quick insight into what your current code does:

ILIST l1(4,10), l2(4,20), l3(4,30);

Three local variables.

VLIST vec;

A local vector.

vec.push_back(l1);

The vector now allocates some dynamic memory to store at least one ILIST, and then copies the contents of l1 into that memory. The two are now independent.

If you want to have a vector that is essentially a view, that allows you to manipulate the destination objects through it, you are going to need to store a pointer or a reference in your vector:

#include <iostream>
#include <list>
#include <vector>

using ilist_t = std::list<int>;
using vecilist_t = std::vector<ilist_t*>;

int main()
{
    ilist_t il;  // empty list
    vecilist_t vec;  // empty vector

    vec.push_back(&il);  // store address in vec[0]

    vec[0]->push_back(42);  // vec[0] has type `ilist_t*`, -> dereferences

    for (int i : il) {
        std::cout << i << '\n';
    }
}

As you've indicated you're a learner, I'll point out that with raw pointers like this it is up to you to ensure that the objects pointed to persist longer than their potential use through the vector:

vecilist_t f() {
    ilist_t i;
    vecilist_t v;
    v.push_back(&i);
    return v;
}

int main() {
    auto v = f();
    v[0]->push_back(42);  // undefined behavior, probably crash
}

The vector returned by f has the address of i which has automatic storage duration - its lifetime ends at the end of the function scope, making the pointer to it in our returned object invalid and Undefined Behavior would ensue.

--- EDIT ---

It's not clear why you need the freestanding lists. If all you want is a vector of 3 lists, you can do the following:

#include <vector>
#include <list>

using ilist_t = std::list<int>;
using ilvec_t = std::vector<ilist_t>;

int main() {
    ilvec_t ilvec;
    ilvec.resize(3);  // now contains 3 empty lists.

    // push a value onto the 2nd list
    ilvec[1].push_back(42);
}

If your vector is going to have a compile-time fixed size, you can use std::array instead.

using ilarray_t = std::array<ilist_t, 5>;  // compile time size fixed at 5.

Upvotes: 2

Related Questions