关于副本如何工作的问题......我需要一些验证以达到心理健全的目的。如果我有:
multiset<pair<double, string> > myMultiset;
我想将内容打印到控制台......使用时我应该会遇到错误:
copy(myMultiset.begin(), myMultiset.end(), ostream_iterator</.../>(cout, " "));
这是因为对于ostream_iterator的A.我想要传递ostream不喜欢的类型“pair”?如果multiset是由“pair”组成的,即使我只是将类型字符串传递给“ostream”,我觉得尝试一次传递两个元素会导致错误。是否有一个迭代器将迭代只是键或只是值?有一个干净的方法来处理这个?每次我最后只写“for()”循环,以便我可以获得“iter-&gt; first”和“iter-&gt; second”的内容......我是STL Algo的新手,但是我喜欢清洁的想法,我想利用他们的能力...虽然很多minutae ...
答案 0 :(得分:4)
std::copy()
未能按原样运作的原因是因为std::operator<<()
没有定义std::pair
。用户可以通过多种合理的方式对一对进行文本格式化,并且该标准使其未定义。您可以自己定义一个:
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;
});
你可能会发现密钥提取lambda非常有用,并且可以使用实用程序函数来重用它:
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
循环会使事情变得更简单,更简洁,更容易理解。新的基于范围的for
循环更进一步:
for( auto p : set ) {
std::cout << p.first << ' ';
}
这将与其他方法略有不同,因为它会在末尾留下悬空空间分隔符。它也只适用于容器;如果你有一对迭代器而不是一个容器(比如,一对std::istream_iterator
或一对任意迭代器到容器中)那么你应该使用一个算法。但我认为,因为它是最简单,最清晰的一群。
答案 1 :(得分:1)
您使用的是C ++ 11吗?如果是这样,您可以使用带有lambda的transform
算法来提取密钥(或值)。
你可以在较旧的C ++中做类似的事情,但它有点麻烦。