创建STL映射键迭代器
Creating a STL map key-iterator
通常,您有一个类似map<string,X>
的映射,其中键是映射值的名称,并且您需要一个API,它可以让消费者看到所有名称。。。以填充例如GUI列表框。您可以构建一个向量并将其作为API调用返回,但这是非常低效的。您可以只返回对映射的引用,但这些值也可以访问,您可能不希望这样。
那么,如何编写一个兼容的类KeyIterator呢?它封装映射并提供对该映射中键的标准迭代器访问。
例如:
map<string,X> m= ...
KeyIterator<string> ki(m);
for(KeyIterator<string>::iterator it=ki.begin();it!=ki.end();++it)
cout << *it;
KeyIterator应该是轻量级的,这样您就可以从一个几乎没有开销的方法返回它。
编辑:我不确定我是否解释得很完美,让我给出一个更好的用例(半伪(:
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;
}
#include <map>
#include <string>
#include <iterator>
template <class map>
class KeyIterator {
typename map::const_iterator iter_;
public:
KeyIterator() {}
KeyIterator(typename map::iterator iter) :iter_(iter) {}
KeyIterator(typename map::const_iterator iter) :iter_(iter) {}
KeyIterator(const KeyIterator& b) :iter_(b.iter_) {}
KeyIterator& operator=(const KeyIterator& b) {iter_ = b.iter_; return *this;}
KeyIterator& operator++() {++iter_; return *this;}
KeyIterator operator++(int) {return KeyIterator(iter_++);}
const typename map::key_type& operator*() {return iter_->first;}
bool operator==(const KeyIterator& b) {return iter_==b.iter_;}
bool operator!=(const KeyIterator& b) {return iter_!=b.iter_;}
};
int main() {
std::map<std::string,int> m;
KeyIterator<std::map<std::string,int> > ki;
for(ki=m.begin(); ki!=m.end(); ++ki)
cout << *ki;
}
http://codepad.org/4wxFGGNV
没有比这更轻的了。然而,它要求迭代器在map类型上模板化,而不是键类型,这意味着如果您试图隐藏内部,则必须提供一些实现细节。
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。您将无法仅在键类型上对其进行模板化,因为它必须包含对映射的某种引用;你需要地图的完整定义。
您的请求使问题过于复杂,因为您必须定义两种不同的类型,KeyIterator
和KeyIterator::iterator
。
这是使用我的类的示例代码:
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;
}
我想主要的问题是你只想要一个模板参数而不是两个:KeyIterator<string>
而不是KeyIterator<string, X>
。
要实现这一点,您可能需要一种称为类型擦除的技术。不过,这将涉及动态分配和虚拟方法调用。
如果是后者,您只需包装一个map<string, X>::const_iterator
,使取消引用返回对键的引用,并提供采用映射迭代器的构造函数。
- 错误 C2760:语法错误:映射迭代器上意外的标记"标识符",预期的";"
- 映射迭代器与运算符不匹配
- 使用迭代器替换映射中的常量项的方法
- 映射中循环的迭代器
- std::使用迭代器映射查找距离,程序不会终止
- 创建以向量/列表迭代器为键的映射
- 我可以将映射迭代器与 OpenMP 并行使用吗?
- c++ 在循环中删除迭代器(映射的映射)
- std::map 擦除 - 将迭代器传递给错误的映射
- BAD_ACCES映射 C++ 上的迭代器
- 映射/集迭代器不可取消引用 (C++) - 调试断言失败
- 取消引用映射迭代器时返回对临时的引用
- 来自并发哈希映射的迭代器是否安全
- 为什么映射迭代器显示基本操作数无效错误
- C++有关映射和迭代器的错误
- 复制映射迭代器对值的省略
- ->第一个/第二个到空映射迭代器开始
- 将迭代器映射到特定字段上的迭代器(可以使用 Boost)
- c++如何将迭代器映射的集合作为键
- 有没有一种方法可以将迭代器映射到它的容器