2

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

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;

因此,有了这个迭代器成员,这两行的输出将是相同的。

这怎么可能?

4

1 回答 1

2

您需要一个存储一些状态的迭代器:

  • 它在哪里(例如迭代v_itv
  • 它要去哪里(例如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也是礼貌的。您应该提供增量前和增量后的表格。

您还需要==and!=比较,比较v_itandforward和 dereference 运算符*->that dereference v_it,以及合适begin的 andend函数;对于奖励积分,一个const_iterator会很好。

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

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

于 2013-01-21T19:03:58.647 回答