你真的不應該試圖將習語直接從一種語言翻譯成另一種語言。在C++中,您通常不會編寫採用迭代器並生成新迭代器的函數;相反,你可以編寫帶有輸入和輸出迭代器的函數,並從一個複製到另一個。因此,您可以編寫一個zip
函數,該函數採用T
以上的輸入迭代器,通過U
的輸入迭代器以及採用pair<T, U>
以上的輸出迭代器。
但是,你不打算把這兩個調用以這種方式連接起來,因爲你的zip
函數不會返回任何可以有用地傳遞給任何類型的dict
函數的任何東西(比如迭代器範圍)。相反,您可以創建一個dict
模擬(unordered_map
),在其中創建輸出迭代器,並使用zip
函數將對複製到其中。
事情是這樣的:
template <I1, I2, O>
void zip(I1 it1, I1 it1end, I2 it2, I2 it2end, O o) {
while ((it1 != it1end) && (it2 != it2end)) {
*o++ = std::make_pair(*it1++, *it2++);
}
}
std::unordered_map<T, U> mapping;
zip(c1.begin(), c1.end(), c2.begin(), c2.end(), std::inserter(mapping, mapping.end()));
除了我不認爲你可以實際使用上unordered_map
這樣或那樣不inserter
,所以你必須寫一個map_inserter
函數。
如果您不知道本地的各類T
和U
,您可能希望以提取從元素類型的迭代器的類型,所以你可以auto
它一個函數模板來包裝這一切了。 (在C++ 11,你可以decltype
它不需要的功能,但表達將是一個爛攤子。)
如果你有一個zip
和map_inserter
多種用途,它可能是值得寫他們。但除此之外,一個更好的解決辦法是將它擴展到外在的循環:
auto it1 = c1.begin(), it1end = c1.end(), it2 = c2.begin(), it2end = c2.end();
std::unordered_map<T, U> mapping;
while ((it1 != it1end) && (it2 != it2end)) {
mapping[*it1++] = *it2++;
}
是的,我通常不會直接在實踐中做到這一點,我相信在不直接翻譯成語時也是如此。我只是好奇什麼是最好的和適當的「C++方式」來解決同樣的問題 – 2014-11-03 19:29:38
我會寫非常不同的zip。我希望它像容器一樣,這樣的用法可以像'for(auto pr:zip(c1,c2)){...}'。我認爲這比OutputIterator風格的算法更有用。 – Barry 2014-11-03 19:40:38
@Barry:我同意這樣的事情更有用,但他們並不真正適合STL算法的成語。 (順便說一句,我沒有捍衛STL算法的習慣,我一直喜歡它,直到我發現其他語言中的惰性列表和Python生成器之類的東西,並且注意到它不需要每隔一段時間就使用這些算法,很多腳手架,你可以一直使用它們...這是我不像以前那麼多使用C++的原因之一。 – abarnert 2014-11-03 19:41:59