如何在C++的std::set中提前结束迭代?

9

C++

我有以下迭代循环:

for (it = container.begin(); it != container.end(); ++it) {
    //my code here
}

我想提前结束这个迭代1. 我尝试了以下方法,但它不能编译:

for (it = container.begin(); it != container.end() - 1; ++it) { //subtract 1
    //my code here
}

这该怎么做呢?谢谢。

4
在您的代码中,"result"和"container"是否指同一个东西? - taocp
5个回答

15

您可以迭代至s集合的std::prev(s.end())之前,注意容器为空的可能性:

#include <iterator> // for std::prev

auto first = s.begin();
auto last = s.empty() ? s.end() : std::prev(s.end()); // in case s is empty
for (auto it = first; it != last; ++it) { ... }

Note: std::prev需要C++11支持。 C++03的替代方案为--s.end()


1
@bames53,没有足够的上下文来确定检查是否是不必要的。应该很容易弄清楚如何去掉这个检查。 - juanchopanza
1
@juanchopanza(当然我并没有真的投反对票,我只是在逗 Yakk 玩。你所说的同样适用于抱怨代码会在空容器上崩溃的情况;即,没有足够的上下文来知道需要检查。如果有必要,很容易想出如何添加检查。) - bames53
@DaveS 如果代码通过构造保证容器不会为空,则从未经检查的递减一过去的末尾迭代器不会存在UB的可能性。 - bames53
1
@bames53 哦,好的,明白了。是的,当然是双向的。我认为现在的答案已经包含足够的信息,让OP可以根据自己的需求进行操作。 - juanchopanza
@amorimluc 你是否支持C++11?如果不支持,你可以用std::advance(s.end(), -1)替换对std::prev(s.end)的调用。 - juanchopanza
显示剩余5条评论

2
尝试使用 std::prev
for (it = container.begin(); it != std::prev(container.end()); ++it) { //subtract 1
    //my code here
}

检查容器是否为空并避免段错误并不难。 - Yakk - Adam Nevraumont
1
@Yakk 而且如果代码保证容器不为空,则检查可能是完全不必要的。 - bames53
1
@Yakk 我假定楼主自己可以弄清楚那个。 - Pubby
这里的'result'是什么? - user2918461

0

寻找最后一个迭代器的C++98解决方案可以如下:

set.find(*set.rbegin())

另一种选择是使用未记录且不被人们推荐的选项。

it!= --set.end()

同样有效,当设置为空时(begin == end),其行为应该是未定义的


0
for (it = container.begin(); it != --result->container.end(); ++it) { //subtract 1
    //my code here
}

std::set::iterator 是双向迭代器,这意味着您可以对其执行 --++ 操作。但是,它不满足随机访问迭代器的要求,因此您不能使用 -+ 操作。


@Yakk 对,但如果早期代码保证容器不为空,那就完全没问题。 - bames53
@Yakk 那么问题陈述就不适用了。 - Joseph Mansfield

0

result->container.end() - 1 需要一个随机访问迭代器,但你只有一个双向迭代器。相反,你可能想要使用 --result->container.end()

此外,你可能不想每次重新计算它,虽然这并不是什么大问题:

for (auto i(begin(result->container)), e(--end(result->container)); i!=e; ++i) {

我喜欢终止迭代器的缓存。 - Yakk - Adam Nevraumont
为什么/如何使用 end(result->container) 而不是 result->container.end() - chew socks
为什么:风格偏好;如何:标准库提供了这个函数,并且可以通过参数相关查找找到,或者我们可以明确地编写 std::end(result->container) - bames53

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接