创建STL映射键迭代器 [英] Creating a STL map key-iterator

查看:102
本文介绍了创建STL映射键迭代器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

通常,您有一个地图 map< string,X> ,其中键是映射值的名称,您需要一个API,名称...填充例如GUI列表框。
你可以构建一个向量并将其作为一个API调用返回,但这是相当低效的。

Often, you have a map like map<string,X> where the key is the name of the mapped value, and you need an API which lets consumers see all the names... to populate a GUI list-box for example. You can build a vector and return it as an API call but this is rather inefficient. You could just return a reference to the map, but then the values are also accessible and you might not want that.

你可以写一个符合的类KeyIterator,

So how could you write a compliant class, KeyIterator, which wraps map and provides standard iterator access to the keys in that map.

例如:

map<string,X> m= ...
KeyIterator<string> ki(m);
for(KeyIterator<string>::iterator it=ki.begin();it!=ki.end();++it)
 cout << *it;

KeyIterator应该是轻量级的,所以你可以从几乎没有开销的方法返回它。

KeyIterator should be lightweight so you can return it from a method with virtually no overhead.

编辑:
我不确定我是否解释完全,让我给一个更好的用例(半伪):

edit: I'm not sure I explained perfectly, let me give a better use-case (semi-pseudo):

class PersonManager
{
 private:
  map<string,Person> people;
 public:
  //this version has to iterate the map, build a new structure and return a copy
  vector<string> getNamesStandard();

  //this version returns a lightweight container which can be iterated
  //and directly wraps the map, allowing access to the keys
  KeyIterator<string> getNames();
};

void PrintNames(PersonManager &pm)
{
 KeyIterator<string> names = pm.getNames();
 for(KeyIterator<string>::iterator it=names.begin();it!=names.end();++it)
  cout << *it << endl;
}


推荐答案

template<typename iterator_type>
class KeyIterator
{
    iterator_type iterator;
public:
    typedef typename std::iterator_traits<iterator_type>::value_type::first_type value_type;
    KeyIterator(iterator_type i) : iterator(i) {}
    value_type operator*() { return iterator->first; }
    KeyIterator & operator++() { ++iterator; return *this; }
    bool operator!=(const KeyIterator & right) const { return iterator != right.iterator; }
    // ...
};

编辑:看到您的编辑后,我发现这不是你问。你困惑我通过调用你的类KeyIterator,一个更合适的名字将是KeyContainer。你不能仅仅对键类型进行模板,因为它必须包含对地图的某种引用;您需要完全定义地图。

After seeing your edit I realize this isn't exactly what you asked for. You confused me by calling your class a KeyIterator, a more appropriate name would be KeyContainer. You won't be able to template it just on the key type, since it's going to have to contain some kind of reference to the map; you'll need the full definition of the map.

您的请求过于复杂,因为您必须定义两种不同的类型, KeyIterator KeyIterator :: iterator

Your request overcomplicates the problem because you must define two different types, KeyIterator and KeyIterator::iterator.

下面是使用我的类的示例代码:

Here's your sample code using my class:

class PersonManager
{
private:
    map<string,Person> people;
public:
    //this version has to iterate the map, build a new structure and return a copy 
    vector<string> getNamesStandard(); 

    //this version returns a lightweight container which can be iterated 
    //and directly wraps the map, allowing access to the keys 
    KeyIterator<map<string,Person>::iterator> getNamesBegin(); 
    KeyIterator<map<string,Person>::iterator> getNamesEnd(); 
}; 

void PrintNames(PersonManager &pm) 
{ 
    KeyIterator<map<string,Person>::iterator> it = pm.getNamesBegin();
    KeyIterator<map<string,Person>::iterator> end = pm.getNamesEnd();
    for(it; it!=end; ++it) 
        cout << *it << endl; 
}

这篇关于创建STL映射键迭代器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆