【发布时间】:2018-01-10 12:47:32
【问题描述】:
我有两个迭代器(比如it1 和it2)到同一个std::set<int>。它们是通过lower_bound 和upper_bound 获得的,因此它们不能安全地取消引用(它们可以等于end())。
有没有一种简单安全的方法来判断哪个先行?
我可以打电话给std::distance(it1, it2) 和std::distance(it2, it1),但这似乎没有帮助,因为如果it1 != it2 那么其中一个电话是UB。我可以测试*it1 < *it2,但前提是没有迭代器指向end()。最后,我可以先测试结束迭代器,然后对值进行上述比较。
是否有一个纯粹基于迭代器而不涉及值的优雅解决方案,即取消引用?我愿意最多使用 c++14 并且可能会提升。
EDIT(响应 cmets): 我使用集合是因为我想要快速查找和插入,特别是比线性复杂度快得多。排序后的向量是一种可能的替代方案,它可以轻松解决问题,但插入和删除是线性时间操作。
【问题讨论】:
-
lower_bound和upper_bound返回的迭代器将始终定义一个有效范围:[lower, upper)。你不需要检查它。如果两者相等,则范围为空,就像任何其他范围一样。 -
除非你的意思是你有类似
auto [it1, it2] = set.equal_range(value); if (rand()%2) swap(it1, it2);的东西 -
迭代器不是来自相同值的下界和上界,并且逻辑有些涉及,因此迭代器可以按任何顺序排列。不过,我当然可以跟踪传递给绑定函数的值...
-
“有没有优雅的解决方案”是的,改变逻辑,所以迭代器总是按顺序排列
-
明显的解决方案是使用排序向量而不是
std::set<>,但没有足够的细节来说明这种解决方案是否可行