Aki*_*ira 3 c++ iterator c++14
我必须使用我无法更改的外部库。该库以及其他库可以通过其内部逻辑标记特殊格式的文件。令牌生成器提供了一个用于访问令牌的迭代器接口,类似于以下简化示例:
class Tokenizer {
public:
/* ... */
Token token() const; // returns the current token
Token next() const; // returns the next token
bool hasNext() const; // returns 'true' if there are more tokens
/* ... */
};
Run Code Online (Sandbox Code Playgroud)
我想执行一个迭代包装器所呈现的Tokenizer
它允许使用标准的算法库(std::copy_if
,std::count
等)。更具体地说,如果迭代器包装器满足输入迭代器的要求就足够了。
我目前的试验如下所示:
class TokenIterator {
public:
using iterator_category = std::input_iterator_tag;
using value_type = Token;
using difference_type = std::ptrdiff_t;
using pointer = const value_type*;
using reference = const value_type&;
explicit TokenIterator(Tokenizer& tokenizer) :
tokenizer(tokenizer) {
}
TokenIterator& operator++() {
tokenizer.next();
return *this;
}
value_type operator*() {
return tokenizer.token();
}
private:
Tokenizer& tokenizer;
};
Run Code Online (Sandbox Code Playgroud)
我陷入了像begin
and end
、相等比较器等函数的实现中。所以,我的问题是:
TokenIterator
指示令牌序列结束的实例(即hasNext() == false
),以及如何将其与另一个TokenIterator
实例进行比较以确定它们是否相同?operator*()
而不是引用返回一个值,这是一个好方法吗?首先,我建议仔细查看http://www.boost.org/doc/libs/1_65_1/libs/iterator/doc/iterator_facade.html
我发现它大大减少了这样的代码所需的样板数量。
然后,您必须决定如何表示已到达“结束”的迭代器。一种方法是将默认构造的迭代器设为“结束”迭代器。它不包含任何对象,您不能增加或取消引用它。“开始”迭代器则是一个非默认构造的迭代器。它有一个对象,您可以取消引用它。增加这个迭代器只是检查hasNext()
. 如果为 true,则将包含的对象设置为next()
。如果为 false,则清除包含的对象并使这个迭代器看起来像一个默认构造的迭代器。
从operator*
. 即使您分配给引用,生命周期扩展也会保留该值,直到引用超出范围。也就是说,任何假定此类引用在多次迭代中仍然有效的代码都会中断,因此请坚持使用 simplefor (auto val : tokens)
或for (auto& val : tokens)
.
归档时间: |
|
查看次数: |
544 次 |
最近记录: |