initializing vector of lists with already initialised lists

I wonder if I can shorten the code by someway initializing the vector of lists with predefined lists already in the same initialization (sorry if my question is unclear, please look to the code below

1
2
3
4
5
6
7
// usual way
    std::list<std::string> Question1;
    std::list<std::string> Question2;
    std::list<std::string> Question3;
    std::list<std::string> Question4;
    std::vector<std::list<std::string>> Questions;
    Questions = {{Question1}, {Question2},{Question3}, {Question4}};


Just out of curiosity ,is there any shorter way to describe it, smth like:

1
2
3
4
5
6
//Pseudocode
std::vector<std::list<std::string>> Questions = (
                                    {std::list<std::string> Question1}, 
                                    {std::list<std::string> Question1}, 
                                          ......)
1
2
3
4
  std::vector< std::list< std::string > > v = {
    {"hola", "mundo", "feliz"},
    {"oh", "brave", "new", "world"}
  };
"hola", "mundo", "feliz" must be initialized before adding them to the vector.

My question if it is possible to initialize the list at the same time you are initializing the vector.

I guess that its not possible.
"hola", "mundo", "feliz" must be initialized before adding them to the vector.
My question if it is possible to initialize the list at the same time you are initializing the vector.

The code proposed by ne555 does exactly that. Or what else do you need?

Anyway, instead of hard-coding everything, it would be more elegant and flexible to do something like this:
1
2
3
4
5
std::vector<std::list<std::string>> questions;
for (size_t i = 0; i < TOTAL_NUMBER_OF_QUESTIONS; ++i)
{
    questions.push_back(init_question(i));
}

...and implement a function:
1
2
3
4
std::list<std::string> init_question(const size_t i)
{
    /*your code to initialize (e.g. load from file or DB) the i-th question here*/
}



BTW: Do you really need std::vector<std::list<std::string>> and can't use std::vector<std::vector<std::string>> or even std::vector<std::array<std::string,N>> instead?
Last edited on
> My question if it is possible to initialize the list at the same time you are initializing the vector.

No, not at the same time (there won't be a race condition). They are initialised one after the other; the vector is constructed after its lists are constructed, each list is constructed after its strings are constructed.

They can all be initialised by with a single statement in source code. For example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <iostream>

namespace not_std {

    struct string { string( const char* cstr) { std::cout << "string '" << cstr << "' constructor\n" ; } };
    template < typename T > struct list { list( std::initializer_list<T> ) { std::cout << "list constructor\n" ; } };
    template < typename T > struct vector { vector( std::initializer_list<T> ) { std::cout << "vector constructor\n" ; } };
}

int main()
{
    [[maybe_unused]] not_std::vector< not_std::list< not_std::string > > v = {

    {"hola", "mundo", "feliz"},
    {"oh", "brave", "new", "world"}
  };
}

string 'hola' constructor
string 'mundo' constructor
string 'feliz' constructor
list constructor
string 'oh' constructor
string 'brave' constructor
string 'new' constructor
string 'world' constructor
list constructor
vector constructor

http://coliru.stacked-crooked.com/a/96e76aedd0f919af
Last edited on
Thank you very much.

@kigar6451, I've read that list is better than vector if many non-random insertions/deletions are used. And for filling up them, yes, I am using the functions as per your example.


@JLBorges, yes, this is exactly what I was looking for. Thanks.
Last edited on
ragnarokas wrote:
I've read that list is better than vector if many non-random insertions/deletions are used. And for filling up them, yes, I am using the functions as per your example.


std::list (linked list) can, in theory, be faster, if you frequently insert/delete elements in the middle of the list.

(but benchmarks show that this is not necessarily the case, due to bad cache locality of std::list)

std::deque is supposed to be faster, if you frequently add/remove elements at the beginning or end of the list.

For anything else, std::vector is probably the simplest and fastest "list" (sequence container) class.


It appears to me, you just initialize your "lists" with a certain size and don't change them much afterwards.

Thus I'd probably go with:
1
2
3
4
5
6
std::vector<std::string> list;
list.reserve(42); // <-- pre-allocate capacity, so that no re-allocations are needed in the following
for (size_t i = 0; i < 42; ++i)
{
    list.push_back("test");
}

Last edited on
Topic archived. No new replies allowed.