2014-06-08 11 views
6

powiedzieć, że jestem inicjalizacji vector<vector<string>> tak:Scal wektor i initializer_list w inicjalizacji wektora <vector<T>>?

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

Załóżmy teraz chcę dołączyć już istniejący vector<string> do niektórych elementów v „s. Tak:

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

To składnia oczywiście nie działa, ponieważ operator+ nie jest zdefiniowane w taki sposób.

Rozumiem, że jest to możliwe do skonstruowania v pierwszą drogę, a następnie napisać

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

Ale to nie jest wygodne, ponieważ mogę mieć kilka suffix wektory, które są dołączone do dowolnego v[i]. Chcę, aby suffix było razem z inicjalizacją v[i], więc ma sens i nie muszę przesuwać indeksów, jeśli dodaję/usuwam elementy z inicjalizacji v.

Odpowiedz

3

Jednym z możliwych rozwiązań jest użycie funkcji pomocnika, która wykonuje dołączanie.

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

I użyć go do zainicjowania zmiennej.

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

Aktualizacja

Bardziej efektywne wdrożenie appendStrings (dzięki @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; 
} 
+0

Jeśli 's1' jest lista inicjator, uniknąć alokacji. Jeśli "ruszysz", powróć, unikaj innego. – Yakk

+0

@Yakk, myślę, że rozumiem część zwrotu "przenieś", ale nie mam pojęcia, co masz na myśli przez pierwszą część komentarza. –

+0

Zmień "Wektor &&' na 'std :: initializer_list ' (lub 'T'). Stwórz 'wektor' w tym' rezerwie' wystarczający dla wspomnianej listy i 2. 'wektora', następnie załaduj go i zwróć. Uzyskaj 1 alokację pamięci plus 1 na 'std :: string' przydzielony, zamiast swojego ... 3? plus 2 na 'std :: string' (' move' upuszcza go na 2 + 1). Tylko mikrooptymalizacja. – Yakk

Powiązane problemy