标准容器上带有迭代器的特定路径

时间:2013-01-21 18:25:04

标签: c++ iterator std

我有一个带有标准容器成员的类,我想知道是否可能使用特定路径创建自己的迭代器,例如它来回移动,然后停止。

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;

因此,使用此迭代器成员,这两行中的输出将是相同的。

这怎么可能?

1 个答案:

答案 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_itforward,以及取消引用操作符*->取消引用v_it,以及合适的beginend函数;对于奖励积分,const_iterator会很好。

请注意,如果您确实希望问题中的代码(i < s.end()而不是更通用的i != s.end())能够正常工作,则需要随机访问;这是完全可能的,但如果你不需要它,那就相当过分了。

更新:如评论中所述,这个特定的实现可能会有所改善;例如,如果您对如何定义结束迭代器有点小心,则可以删除存储v_begin的需要。