测试迭代器是否指向最后一项?

2022-01-10 00:00:00 iterator c++ stl

我有一个由 std::find() 产生的 stl 迭代器,并希望测试它是否是最后一个元素.一种写法如下:

I have an stl iterator resulting from a std::find() and wish to test whether it is the last element. One way to write this is as follows:

mine *match = someValue;
vector<mine *> Mine(someContent);
vector<mine *>::iterator itr = std::find(Mine.begin(), Mine.end(), match);

if (itr == --Mine.end()) {
  doSomething;
}

但在我看来,递减 end() 迭代器是自找麻烦,例如如果向量没有元素,那么它将是未定义的.即使我知道它永远不会是空的,它仍然看起来很丑.我在想也许 rbegin() 是要走的路,但不确定将正向迭代器与反向迭代器进行比较的最佳方法.

But it seems to me that decrementing the end() iterator is asking for trouble, such as if the vector has no elements, then it would be undefined. Even if I know it will never be empty, it still seems ugly. I'm thinking that maybe rbegin() is the way to go, but am not certain as to best way to compare the forward iterator with a reverse iterator.

推荐答案

这样做:

// defined in boost/utility.hpp, by the way
template <typename Iter>
Iter next(Iter iter)
{
    return ++iter;
}

// first check we aren't going to kill ourselves
// then check if the iterator after itr is the end
if ((itr != Mine.end()) && (next(itr) == Mine.end()))
{
    // points at the last element
}

就是这样.永远不会给你未定义的行为,适用于所有迭代器,美好的一天.

That is all. Never gives you undefined behavior, works on all iterators, good day.

为了好玩而总结一下:

template <typename Iter, typename Cont>
bool is_last(Iter iter, const Cont& cont)
{
    return (iter != cont.end()) && (next(iter) == cont.end())
}

给予:

if (is_last(itr, Mine))

<小时>

如果您对实用功能/好看的代码过敏,请执行以下操作:


If you're allergic to utility functions/nice looking code, do:

if ((itr != Mine.end()) && (itr + 1 == Mine.end()))

但是你不能在非随机访问迭代器上这样做.这个适用于双向迭代器:

But you can't do it on non-random-access iterators. This one works with bidirectional iterators:

if ((itr != Mine.end()) && (itr == --Mine.end()))

而且是安全的,因为 end() >itr 由第一次检查.

And is safe since end() > itr by the first check.

相关文章