迭代一个std ::地图的键/值在C ++中 [英] Iterating over keys/values of a std::map in C++
问题描述
我的问题是这个轻微的概括。为了讨论起见,我将专注于迭代地图的钥匙。我想有一个通用的辅助函数, key_iterator
,这需要一个map迭代器,并返回一个地图密钥迭代器。例如,下面的code:
My question is a slight generalization of this one. For sake of discussion, I'll focus on iterating over the keys of a map. I would like to have a generic helper function, key_iterator
, that takes a map iterator and returns a map key iterator. For example, the following code:
#include "key_iterator.hpp"
#include <algorithm>
#include <iostream>
#include <iterator>
#include <map>
int main(int argc, char** argv)
{
std::map<std::string, int> m;
m["One"] = 1;
m["Two"] = 2;
std::copy(key_iterator(m.begin()), key_iterator(m.end()), std::ostream_iterator<std::string>(std::cout, " "));
return 0;
}
应该产生下面的输出:
should produce the following output:
One Two
作为解决上面提到的问题的建议,提振:: transform_iterator似乎是一个合适的起点 key_iterator
的实施。我有一个中途的解决方案,看起来像这样的key_iterator.hpp:
As suggested in the solution to the question referred to above, boost::transform_iterator seems like an appropriate starting point for the implementation of key_iterator
. I have a half-way solution that looks like this for key_iterator.hpp:
#pragma once
#include <functional>
#include <map>
#include <boost/iterator/transform_iterator.hpp>
template <typename Key, typename Value>
class KeyGetter : public std::unary_function<std::pair<Key,Value>, Key>
{
public:
const Key& operator()(const std::pair<Key,Value>& p) const {return p.first;}
};
template<typename Key, typename Value>
boost::transform_iterator<KeyGetter<Key,Value>, typename std::map<Key,Value>::iterator>
key_iterator(typename std::map<Key,Value>::iterator itr)
{
return boost::make_transform_iterator<KeyGetter<Key,Value>, typename std::map<Key,Value>::iterator>(itr, KeyGetter<Key,Value>());
}
但这个实施的关键和值类型没有被自动推断,我需要手动提供他们得到它来编译:
but with this implementation the Key and Value types are not being deduced automatically and I need to supply them manually to get it to compile:
std::copy(key_iterator<std::string,int>(m.begin()), key_iterator<std::string,int>(m.end()), std::ostream_iterator<std::string>(std::cout, " "));
这是如何得到这个工作,我想要的方式有什么想法?
Any thoughts on how to get this working the way I want?
推荐答案
试试这个:
template <typename Iter>
struct KeyGetter : std::unary_function<typename Iter::value_type,
typename Iter::value_type::first_type>
{
const typename Iter::value_type::first_type& operator()
(const typename Iter::value_type& p) const
{ return p.first; }
};
template<typename Iter>
boost::transform_iterator<KeyGetter<Iter>, Iter> key_iterator(Iter itr)
{
return boost::make_transform_iterator<KeyGetter<Iter>, Iter>
(itr, KeyGetter<Iter>());
}
这个想法是,在调用点的功能应在它的参数直接模板,以避免显式地指定模板参数。
The idea being that the function at the call site should be templated directly on its argument, to avoid having to specify the template arguments explicitly.
这篇关于迭代一个std ::地图的键/值在C ++中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!