我有一个带有标准容器成员的类,我想知道是否可能使用特定路径创建自己的迭代器,例如它来回移动,然后停止。
template<class T>
class compressed_string {
vector<T> v;
public:
typedef typename std::vector<T>::iterator iterator;
iterator begin() { return v.begin(); }
iterator end() { return v.end(); }
compressed_string& add(const T& elem) {
v.push_back(elem);
return *this;
}
basic_string<T> not_nice_way_to_make_real_string() {
basic_string<T> tmp;
for(iterator i = v.begin(); i < v.end(); ++i)
tmp += *i;
for(iterator i = --v.end(); i >= v.begin(); --i)
tmp += *i;
return tmp;
}
};
主:
compressed_string<char> s;
s.add('q').add('w').add('e').add('w');
cout << s.not_nice_way_to_make_real_string(); // q w e w w e w q
cout << endl
for ( compressed_string<char>::iterator i = s.begin(); i < s.end(); ++i )
cout << *i;
因此,使用此迭代器成员,这两行中的输出将是相同的。
这怎么可能?
答案 0 :(得分:2)
你需要一个存储一些状态的迭代器:
v_it
上的迭代器v
)bool forward
)v_begin = v.begin()
和v_end = v.end()
)以及一些表示结尾的无效迭代器,例如{v_end, backward}
)。
然后沿着以下行实现递增运算符:
if (forward) {
if (++v_it == v_end) {
forward = false;
--v_it;
}
} else {
if (v_it-- == v_begin) {
v_it = v_end;
}
}
,类似于减量,如果你想要一个双向迭代器;在这种情况下,提供reverse_iterator
也是礼貌的。您应该提供增量前和增量后的表格。
您还需要进行==
和!=
比较,比较v_it
和forward
,以及取消引用操作符*
和->
取消引用v_it
,以及合适的begin
和end
函数;对于奖励积分,const_iterator
会很好。
请注意,如果您确实希望问题中的代码(i < s.end()
而不是更通用的i != s.end()
)能够正常工作,则需要随机访问;这是完全可能的,但如果你不需要它,那就相当过分了。
更新:如评论中所述,这个特定的实现可能会有所改善;例如,如果您对如何定义结束迭代器有点小心,则可以删除存储v_begin
的需要。