【发布时间】:2011-10-05 20:30:40
【问题描述】:
通常,您有一个像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;
}
【问题讨论】:
-
让 KeyIterator 持有指向映射的指针,并有一个迭代器包装类来包装映射的迭代器,将调用转发到 ++、==、-- 等。应该相对简单,虽然有它仅以键类型为模板将需要某种类型擦除魔法
-
stackoverflow.com/questions/681943/… 这可能会有所帮助
-
嘿@John:说真的,我认为没有任何意义包含在另一个类中。此外,查看@Mark Ransom 和 Mooing Duck 的答案,我没有看到太大的改进,仍然从 @ begin() 开始并在 end() 结束。