如何正确实现自定义迭代器和const_iterators?
我有一个自定义容器类,我想为其编写 iterator 和 const_iterator 类。
我以前从未这样做过,也未能找到合适的操作方法。关于迭代器创建的准则是什么?我应该注意什么?
我还想避免代码重复(我觉得 const_iterator 和 iterator 共享很多东西;一个应该子类化另一个吗?)。
脚注:我很确定 Boost 有一些东西可以缓解这个问题,但由于许多愚蠢的原因,我不能在这里使用它。
I have a custom container class for which I'd like to write the iterator
and const_iterator
classes.
I never did this before and I failed to find an appropriate how-to. What are the guidelines regarding iterator creation, and what should I be aware of ?
I'd also like to avoid code duplication (I feel that const_iterator
and iterator
share many things; should one subclass the other ?).
Foot note: I'm pretty sure Boost has something to ease this but I can't use it here, for many stupid reasons.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
![扫码二维码加入Web技术交流群](/public/img/jiaqun_03.jpg)
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(10)
std::iterator
与random_access_iterator_tag
。这些基类定义了 STL 所需的所有类型定义并执行其他工作。为了避免代码重复,迭代器类应该是一个模板类,并通过“值类型”、“指针类型”、“引用类型”或所有这些(取决于实现)进行参数化。例如:
注意
iterator_type
和const_iterator_type
类型定义:它们是非常量和常量迭代器的类型。另请参阅:标准库参考
编辑:
std::自 C++17 起,iterator
已被弃用。请参阅此处的相关讨论。std::iterator
withrandom_access_iterator_tag
.These base classes define all type definitions required by STL and do other work.To avoid code duplication iterator class should be a template class and be parametrized by "value type", "pointer type", "reference type" or all of them (depends on implementation). For example:
Notice
iterator_type
andconst_iterator_type
type definitions: they are types for your non-const and const iterators.See Also: standard library reference
EDIT:
std::iterator
is deprecated since C++17. See a relating discussion here.我将向您展示如何轻松地为自定义容器定义迭代器,但以防万一,我创建了一个 c++11 库,它允许您轻松地为任何类型的容器(连续或连续的)创建具有自定义行为的自定义迭代器。不连续的。
您可以在 Github 上找到它
以下是创建和使用自定义迭代器的简单步骤:
typedef blRawIterator<类型>迭代器;
typedef blRawIterator<常量类型> const_iterator;
迭代器begin(){return iterator(&m_data[0]);};
const_iterator cbegin()const{return const_iterator(&m_data[0]);};
最后,定义我们的自定义迭代器类:
注意: 定义自定义迭代器时,我们从标准迭代器类别派生,让 STL 算法知道我们创建的迭代器的类型。 >
在这个例子中,我定义了一个随机访问迭代器和一个反向随机访问迭代器:
现在在您的自定义容器类中的某个位置:
I'm going to show you how you can easily define iterators for your custom containers, but just in case I have created a c++11 library that allows you to easily create custom iterators with custom behavior for any type of container, contiguous or non-contiguous.
You can find it on Github
Here are the simple steps to creating and using custom iterators:
typedef blRawIterator< Type > iterator;
typedef blRawIterator< const Type > const_iterator;
iterator begin(){return iterator(&m_data[0]);};
const_iterator cbegin()const{return const_iterator(&m_data[0]);};
Finally, onto defining our custom iterator classes:
NOTE: When defining custom iterators, we derive from the standard iterator categories to let STL algorithms know the type of iterator we've made.
In this example, I define a random access iterator and a reverse random access iterator:
Now somewhere in your custom container class:
他们经常忘记
iterator
必须转换为const_iterator
,而不是相反。有一种方法可以做到这一点:在上面的代码中,请注意
IntrusiveSlistIterator
如何转换为IntrusiveSlistIterator
。如果T
已经是const
这个转换永远不会被使用。They often forget that
iterator
must convert toconst_iterator
but not the other way around. Here is a way to do that:In the above notice how
IntrusiveSlistIterator<T>
converts toIntrusiveSlistIterator<T const>
. IfT
is alreadyconst
this conversion never gets used.Boost 有一些可以提供帮助的东西:Boost.Iterator 库。
更准确地说,此页面: boost::iterator_adaptor 。
非常有趣的是教程示例 显示了自定义类型从头开始的完整实现。
正如已经引用的那样,要点是使用单个模板实现和
typedef
它。Boost has something to help: the Boost.Iterator library.
More precisely this page: boost::iterator_adaptor.
What's very interesting is the Tutorial Example which shows a complete implementation, from scratch, for a custom type.
The main point, as has been cited already, is to use a single template implementation and
typedef
it.不知道Boost有没有什么帮助。
我的首选模式很简单:采用等于
value_type
的模板参数,无论是否为 const 限定。如有必要,还有节点类型。然后,好吧,一切就都各就各位了。只需记住参数化(模板化)所有需要的东西,包括复制构造函数和运算符==。在大多数情况下,const 的语义将创建正确的行为。
I don't know if Boost has anything that would help.
My preferred pattern is simple: take a template argument which is equal to
value_type
, either const qualified or not. If necessary, also a node type. Then, well, everything kind of falls into place.Just remember to parameterize (template-ize) everything that needs to be, including the copy constructor and
operator==
. For the most part, the semantics ofconst
will create correct behavior.有很多好的答案,但我创建了一个 模板标头 我使用它相当简洁易用。
要向你的类添加一个迭代器,只需要编写一个小类来用 7 个小函数来表示迭代器的状态,其中 2 个是可选的:
然后你就可以像你期望的 STL 迭代器一样使用它:
我希望它有帮助。
There are plenty of good answers but I created a template header I use that is quite concise and easy to use.
To add an iterator to your class it is only necessary to write a small class to represent the state of the iterator with 7 small functions, of which 2 are optional:
Then you can use it as you would expect from an STL iterator:
I hope it helps.
我看到这篇文章,很惊讶这里没有真正提到一个简单的方法。使用像 std::iterator 描述的那样指向值的指针显然是非常通用的方法。但你也许可以做一些更简单的事情。当然,这是一种简单化的方法,可能并不总是足够的,但如果是的话,我将其发布给下一个读者。
您的类中的基础类型很可能是一个 STL 容器,它已经为您定义了迭代器。如果是这种情况,您可以简单地使用它们定义的迭代器,而不必真正创建自己的迭代器。
这是一个例子:
I came across this post and was surprised that a simple method is not really mentioned here. Using a pointer to the value like how std::iterator describes is obviously a very generic approach. But you might be able to get away with something much simpler. Of course this is a simplistic approach and might not always be sufficient, but in case it is, I am posting it for the next reader.
Most probably the underlying type in your class is an STL container which already has defined the iterators for you. If that is the case, you can simply use their defined iterators and don't really need to make your own.
Here is an example:
我有兴趣知道这是如何正确,但似乎可以作为内部数据存储的自定义迭代器
然后我只需将它们添加到我的类中,并且似乎按预期工作。
唯一的事情是用
std::cbegin()
、std::rcbegin()
、std::cend()
来实现> 和std::rcend()
函数我必须扩展std
命名空间:i'm interested to know how correct this is, but seems to work as a roll-your-own iterator to internal data storage
Then i just add these to my class, and seems to work as expected.
the only thing is that to make it with the
std::cbegin()
,std::rcbegin()
,std::cend()
andstd::rcend()
functions I have to extend thestd
namespace:已测试代码。
具有自定义迭代器实现的自定义向量
Tested code.
Custom vector with Custom iterator implementation
检查下面的代码,它有效
Check this below code, it works