我有一个Foo
类,其中包含一个map
并提供begin()
和end()
函数对其进行迭代:
class Foo {
typedef std::map<int, double> Container;
typedef Container::const_iterator const_iterator;
Container c_;
public:
const_iterator begin() const { return c_.begin(); }
const_iterator end() const { return c_.end(); }
void insert(int i, double d) { c_[i] = d; }
// ...
};
现在,我想在内部将其从
std::map<int, double>
更改为std::set<int>
,但是我不想破坏任何客户端代码。因此
double d
函数中的insert
现在将被忽略。以下代码仍应有效,其中it->second
现在将始终始终为0.0
:Foo foo;
for(Foo::const_iterator it = foo.begin(); it != foo.end(); ++it) {
std::cout << it->first << " " << it->second << std::endl;
}
如何在
Foo
类中进行这些更改?换句话说,如何提供一个使新内部
Foo::const_iterator
适应旧std::set<int>::const_iterator
行为的std::map<int,double>::const_iterator
?更新:我想摆脱
map
的原因是内存效率。我有数百万个Foo
实例,并且无法在其中存储double
值。 最佳答案
将使用
std::set<std::pair<int, double> >
这样的可比性还不够吗?
否则,您总是可以编写自己的迭代器,该迭代器包装std::list迭代器并提供
first
和second
成员。基本上,您的operator++会在真正的迭代器等上调用operator++,并且取消引用的运算符可以返回临时std::pair(按值)或对存在于迭代器本身中的std::pair的引用(如果您使用的是旧版)代码可以处理)。更新(略作虚构的示例)可能会根据您的方案而起作用:
#include <iostream>
#include <set>
class Foo {
typedef std::set<int> Container;
typedef Container::const_iterator legacy_iterator;
Container c_;
// legacy iterator doesn't have a virtual destructor (probably?), shouldn't
// be a problem for sane usage though
class compat_iterator : public legacy_iterator {
public:
compat_iterator(const legacy_iterator& it) : legacy_iterator(it) {
}
const std::pair<int,double> *operator->() const {
static std::pair<int,double> value;
value = std::make_pair(**this, 0.0);
// Not meeting the usual semantics!
return &value;
}
};
public:
typedef compat_iterator const_iterator;
const_iterator begin() const { return c_.begin(); }
const_iterator end() const { return c_.end(); }
};
int main() {
Foo foo;
for(Foo::const_iterator it = foo.begin(); it != foo.end(); ++it) {
std::cout << it->first << " " << it->second << std::endl;
}
}