jcai
jcai

Reputation: 3593

Merge vector and initializer_list in initialization of vector<vector<T>>?

Say I am initialization a vector<vector<string>> like so:

vector<vector<string>> v;
v = {{
    {"a", "b", "c"},
    {"aa", "bb"},
    {"xyz", "yzx", "zxy"},
    {}
}};

Now suppose I want to append an already existing vector<string> to some of v's elements. Like so:

vector<string> suffix {{"1", "2", "3"}};
vector<vector<string>> v;
v = {{
    {"a", "b", "c"} + suffix,
    {"aa", "bb"},
    {"xyz", "yzx", "zxy"} + suffix,
    {}
}};

That syntax obviously doesn't work because operator+ is not defined in such a way.

I understand that it's possible to construct v the first way and then write

vector<int> indices = {0, 2};
for(int i: indices)
   v[i].insert(v[i].end(), suffix.begin(), suffix.end());

But this is not convenient because I may have several suffix vectors that are attached to arbitrary v[i]. I want the suffix to be together with the initialization of the v[i] so it makes sense and I don't have to shift indices if I add/remove elements from v's initialization.

Upvotes: 7

Views: 2226

Answers (1)

R Sahu
R Sahu

Reputation: 206697

One possible solution is to use a helper function that does the appending.

vector<string> appendStrings(vector<string>&& s1, vector<string> const& s2)
{
   s1.insert(s1.end(), s2.begin(), s2.end());
   return s1;
}

And use it to initialize the variable.

vector<string> suffix {{"1", "2", "3"}};
vector<vector<string>> v = {{
    appendStrings({"a", "b", "c"}, suffix),
    {"aa", "bb"},
    appendStrings({"xyz", "yzx", "zxy"}, suffix),
    {}
}};

Update

A more efficient implementation of appendStrings (Thanks to @Yakk):

vector<string> appendStrings(initializer_list<char const*>&& s1,
                             vector<string> const& s2)
{
   vector<string> ret.
   ret.reserve(s1.size() + s2.size());
   for (auto item : s1 ) {
      ret.emplace_back(item);
   }
   ret.insert(ret.end(), s2.begin(), s2.end() );
   return ret;
}

Upvotes: 4

Related Questions