Cannot use initialization list on two overlapping structs

Viewed 60

I want to use initialization list to initial the variable p1 to simplify things for me. But it's not happening please help. Code is almost self explainatory.

struct word_t {
    int in;
    string word;
    int out;
    word_t(int i, string w, int o): in(i),word(w),out(o) {}
};


struct para_t {
    std::vector<word_t> words;
};

struct song_t { 
    std::vector<para_t> paras;
};    

int main()
{
    //SONG
    std::vector<song_t> song;

    para_t p1{ { 0, "We", 10 }, { 11, "are", 14 } , { 15, "the", 18 } 
    , { 19, "World", 22 } }; // CANNOT INITIALIZE LIKE SO 

    p1.words.push_back(word_t(0, "World", 10));   // THIS WORKS


}
3 Answers

You need one more {}, i.e.

para_t p1{ { { 0, "We", 10 }, { 11, "are", 14 } , { 15, "the", 18 } , { 19, "World", 22 } } };
//       ^                                                                                  ^ <- for para_t
//         ^                                                                              ^   <- for para_t::words
//           ^             ^                                                                  <- for elements (i.e. word_t) in vector

If you initialize a vector of your word_t, it would be like this:

std::vector<word_t> song{ { 0, "We", 10 }, { 11, "are", 14 } , { 15, "the", 18 } 
, { 19, "World", 22 } };

But since your std::vector<word_t> words; is inside struct para_t, you have an extra level, so you should use an extra { } around the initializer list.

Since it's the only member in the struct, consider to make it a typedef:

typedef std::vector<word_t> para_t;
para_t song{ { 0, "We", 10 }, { 11, "are", 14 } , { 15, "the", 18 } 
    , { 19, "World", 22 } };

So you won't need the extra brackets.

You can also add constructor for para_t that takes in std::initializer_list<word_t>.

#include <vector>
#include <string>
#include <initializer_list>

struct word_t {
    int in;
    std::string word;
    int out;
    word_t(int i, std::string w, int o): in(i),word(w),out(o) {}
};


struct para_t {
    std::vector<word_t> words;
    para_t(std::initializer_list<word_t> v) : words{v} {}
};

struct song_t { 
    std::vector<para_t> paras;
};    

int main()
{
    para_t p1{ { 0, "We", 10 }, { 11, "are", 14 } , { 15, "the", 18 }, { 19, "World", 22 } };
}
Related