是否有一个
Java Map keySet()等价于C的std :: map?
Java keySet()方法返回“a set view of the keys contained in this map.”
解决方法
到目前为止所呈现的所有答案最终都是直接创建一个std :: set,这可能并不理想:如果只希望能够迭代键,那么您不希望创建一个全新的容器.
一个更灵活的选择是使用一个转换迭代器,它将一个std :: map迭代器转换成某种类型的迭代器,这个迭代器在取消引用时才产生关键字.这是使用Boost Transform Iterator非常简单的:
#include <functional> #include <boost/iterator/transform_iterator.hpp> // You may already have a select1st implementation; if not,you should :-) template <typename Pair> struct select1st : std::unary_function<const Pair&,const typename Pair::first_type&> { const typename Pair::first_type& operator()(const Pair& p) const { return p.first; } }; template <typename C> boost::transform_iterator< select1st<typename C::value_type>,typename C::const_iterator > begin_keys(const C& c) { return boost::make_transform_iterator( c.begin(),select1st<typename C::value_type>() ); } template <typename C> boost::transform_iterator< select1st<typename C::value_type>,typename C::const_iterator > end_keys(const C& c) { return boost::make_transform_iterator( c.end(),select1st<typename C::value_type>() ); }
使用这些实用功能,您可以将任意范围的std :: map迭代器(或迭代器转换为任何其他对关联容器)转换为仅一个键的范围.举个例子:
#include <iostream> #include <iterator> #include <map> int main() { std::map<int,int> m; m.insert(std::make_pair(1,2)); m.insert(std::make_pair(2,4)); m.insert(std::make_pair(3,6)); std::copy( begin_keys(m),end_keys(m),std::ostream_iterator<int>(std::cout,",")); }
该程序输出:
1,2,3,
如果你真的想要一个包含键的std :: set,你可以使用这些迭代器轻松创建一个:
std::set<int> s(begin_keys(m),end_keys(m));
总的来说,这是一个更灵活的解决方案.
如果你没有Boost或者不想使用Boost或者不能使用Boost,这个特定的变换迭代器可以很容易的实现:
#include <iterator> template <typename C> class key_iterator : public std::iterator< std::bidirectional_iterator_tag,typename C::key_type,typename C::difference_type,typename C::pointer,typename C::reference > { public: key_iterator() { } explicit key_iterator(typename C::const_iterator it) : it_(it) { } typename const C::key_type& operator*() const { return it_->first; } typename const C::key_type* operator->() const { return &it_->first; } key_iterator& operator++() { ++it_; return *this; } key_iterator operator++(int) { key_iterator it(*this); ++*this; return it; } key_iterator& operator--() { --it_; return *this; } key_iterator operator--(int) { key_iterator it(*this); --*this; return it; } friend bool operator==(const key_iterator& lhs,const key_iterator& rhs) { return lhs.it_ == rhs.it_; } friend bool operator!=(const key_iterator& lhs,const key_iterator& rhs) { return !(lhs == rhs); } private: typename C::const_iterator it_; }; template <typename C> key_iterator<C> begin_keys(const C& c) { return key_iterator<C>(c.begin()); } template <typename C> key_iterator<C> end_keys(const C& c) { return key_iterator<C>(c.end()); }
这个用法与Boost版本相同.