【发布时间】:2014-07-24 21:42:31
【问题描述】:
我已经实现了一个稀疏容器,一个基本的查找表 (LUT)。
它基本上是vector<T> 和map<size_t, T> 的混合体:
- 容器是固定大小的(即大小被指定为构造函数参数并且不会改变)
- 每个槽最初在逻辑上都是一些默认值(通常为零)
- 然后调用者可以根据需要在任何插槽读取或写入条目(就像使用
vector) - 然后调用者可以有效地枚举非默认条目
(我实际上如何实现这个容器无关紧要,所以我不会去那里。)
现在我正在尝试为它设计一个迭代器,但我一直在试图弄清楚如何做。
一方面,迭代器应该是随机访问的,因为容器本质上是一个稀疏的vector,否则行为或多或少相同。
另一方面,假设每个插槽的“默认”条目是可忽略的;也就是说,评估像for_each(lut.begin(), lut.end(), func) 这样的东西可以并且确实 必须跳过具有默认值的槽(以显着加速)。
问题:
我如何为这个类正确设计一个迭代器?这样做有意义吗?
目前,我正在考虑实现它,以便 iterator::operator++ 递增迭代器以指向下一个非默认条目,而 iterator::operator+(d) 只是添加一个偏移量 d 而不管该插槽中的条目是否为有效与否。所以“自增”不再是“加1”的意思。
从表面上看,这听起来很荒谬。
但我想不出更好的方法。
有吗?
【问题讨论】:
-
您对
operator++和operator+的想法冲突。实际上,要成为有效的随机访问迭代器,执行it + 5必须与执行it++5 次相同。即使它很稀疏,我仍然希望迭代器迭代每个元素。至少在逻辑上,这些元素仍然存在。 -
@JosephMansfield:“从表面上看,这听起来很荒谬。”...是的,我知道,这正是我问这个问题的原因。你读了吗?
-
@JosephMansfield:关于您的编辑:容器的整个 point 是它仅在那些迭代默认值的情况下使用用户保证条目是无操作的。因此,如果您的期望是它也迭代默认条目,那么您不应该首先使用这个容器。我的问题是,if 您正在使用此容器,因此跳过默认条目 is 是正确的,也是您所期望的(例如,因为您需要降低时间复杂度),您将如何实现行为合理的迭代器?
-
看来你的 API 应该提供两种不同类型的迭代器。
-
@jxh:这实际上是一个很好的答案,你介意将它作为一个发布吗?
标签: c++ iterator containers