2014-06-08 38 views
6

說我初始化vector<vector<string>>像這樣:在矢量<vector<T>>的初始化中合併vector和initializer_list?

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

現在假設我想追加一個已經存在的vector<string>一些v的元素。像這樣:

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

這句法顯然不能因爲operator+是不是以這樣的方式定義的工作。

據我所知,這是可以構建v第一種方式,然後寫

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

但是,這並不方便,因爲我可以有一個連接到任意v[i]幾個suffix載體。我希望suffixv[i]的初始化一起使用,因此它很有意義,如果我從v的初始化中添加/刪除元素,則不必移位索引。

回答

3

一個可能的解決方案是使用輔助函數來執行附加操作。

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

並用它來初始化變量。

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

更新

更有效的實現的appendStrings(感謝@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

如果's1'是一個初始化列表,避免分配。如果你「移動」回來,避免另一個。 – Yakk

+0

@Yakk,我想我明白'移動'返回部分,但我不知道你的評論的第一部分是什麼意思。 –

+0

將'vector &&'更改爲'std :: initializer_list '(或'T')。在那個'reserve'內創建一個'vector',足夠用於所述列表和第二個'vector',然後加載它並返回。獲取1個內存分配,再加上1個分配的std :: string',而不是你的... 3?加上每個'std :: string'2('move'將它放到2 + 1)。只是微型優化。 – Yakk

相關問題