2012-01-29 36 views
1

只是一個關於如何複製工作的問題......我需要一些驗證以達到心理健康的目的。如果我有一個:STL Algo Library副本()

multiset<pair<double, string> > myMultiset; 

,我特林打印出內容來安慰......我應該使用時預期的錯誤:

copy(myMultiset.begin(), myMultiset.end(), ostream_iterator</.../>(cout, " ")); 

這是因爲A.爲ostream_iterator我想傳遞類型「對」,ostream不會喜歡?如果multiset是由「pair」組成的,即使我只是將類型字符串傳遞給「ostream」,我想嘗試一次傳遞兩個元素會導致錯誤。有沒有一個迭代器只會遍歷鍵或值?有沒有一種乾淨的方式來處理這個問題?每次我最終只寫「for()」循環,以便我可以在「iter-> first」和「iter-> second」中獲得內容......我是STL Algo的新手,但我喜歡這個想法的清潔度,我想利用他們的能力......儘管如此多minutae ...

+1

你「感覺」?你爲什麼不嘗試呢? – svick 2012-01-29 14:51:04

+1

答案在這裏:http://stackoverflow.com/questions/312749/providing-an-iterator-for-the-first-element-of-a-container-of-pairs – 2012-01-29 14:51:18

+0

我實際上已經嘗試過其中的變體,計算出去的地方。認爲我試圖做得太快...... – MCP 2012-01-29 17:29:49

回答

4

您的std::copy()不能正常工作的原因是因爲沒有爲std::pair定義的std::operator<<()。用戶可以通過多種合理的方式對文本進行格式化,並且標準使其不確定。您可以定義一個你自己:

template<typename K, typename V> 
std::ostream& operator<<(std::ostream& out, std::pair<K,V> const& p) 
{ 
    return out << p.first; 
} 

// ... 
std::copy(set.begin(), set.end(), 
      std::ostream_iterator<double>(std::cout, " ")); 

或定義一個函數,並使用std::transform()代替:

std::transform(set.begin(), set.end(), 
       std::ostream_iterator<double>(std::cout, " "), 
       [](std::pair<double,std::string> const& p) { 
    return p.first; 
}); 

您可能會發現鑰匙提取拉姆達有用的,肉實用仿出來的重用:

struct keys_of { 
    template<typename K, typename V> 
    K operator()(std::pair<K,V> const& p) const 
    { 
     return p.first; 
    } 
}; 

// ... 
std::transform(set.begin(), set.end(), 
       std::ostream_iterator<double>(std::cout, " "), 
       keys_of()); 

有時for循環使事情變得更簡單,更簡潔,更IM中立可以理解。新的基於範圍的for循環藉此更進一步:

for(auto p : set) { 
    std::cout << p.first << ' '; 
} 

這將表現比其將在年底離開懸空空間分隔符的其他方法略有不同。它也只適用於一個容器;如果你有一對迭代器而不是一個容器(比如說,一對std::istream_iterator或一對任意迭代器放入一個容器中),那麼你應該使用一個算法。但我認爲這是最簡單,最清晰的一組。

+0

很多很棒的信息。謝謝! – MCP 2012-01-29 17:30:38

1

您是否使用C + + 11?如果是這樣,您可以使用帶有lambda的transform算法來提取密鑰(或值)。

你可以在舊的C++中做類似的事情,但它有點混亂。