STL Algo图书馆副本()

时间:2012-01-29 14:46:32

标签: c++ algorithm stl

关于副本如何工作的问题......我需要一些验证以达到心理健全的目的。如果我有:

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 ...

2 个答案:

答案 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 ++中做类似的事情,但它有点麻烦。

相关问题