如果我增加了2迭代器时,它指向到一个向量的最后一个元素? 在这个问题问如何通过2元两种不同的方法可供调整迭代STL容器:
- 既可以使用算术运算器的一种形式 - + = 2或两次++
- 或者使用std ::提前()
我已经与VC ++ 7的边缘的情况下进行测试两者当迭代点到STL容器或超出的最后一个元素:
vector<int> vec;
vec.push_back( 1 );
vec.push_back( 2 );
vector<int>::iterator it = vec.begin();
advance( it, 2 );
bool isAtEnd = it == vec.end(); // true
it++; // or advance( it, 1 ); - doesn't matter
isAtEnd = it == vec.end(); //false
it = vec.begin();
advance( it, 3 );
isAtEnd = it == vec.end(); // false
遍历向量和其他容器时,我见过5次的提醒来比较矢量::结束():
for( vector<int>::iterator it = vec.begin(); it != vec.end(); it++ ) {
//manipulate the element through the iterator here
}
显然,如果迭代器前进经过循环中的最后一个元素的for循环语句的比较将计算为假,循环会很乐意继续为未定义行为。
我得到它的权利,如果我曾经使用上一个迭代提前()或任何类型的增值业务,并使其指向过去容器的最后,我将无法检测到这种情况呢? 如果是这样,什么是最好的做法 - 不要用这样的进步?
以下是从尼古拉约祖蒂斯书报价:
请注意,提前()不检查它是否跨越序列的末尾()(它不能检查,因为在一般的迭代器不知道其运行的容器)。 因此,调用此函数可能导致不确定的行为,因为调用operator ++的序列的末尾没有定义
换句话说,维护范围内的迭代器的责任在于完全与呼叫者。
也许你应该有这样的事情:
template <typename Itr>
Itr safe_advance(Itr i, Itr end, size_t delta)
{
while(i != end && delta--)
i++;
return i;
}
您可以在这个过载iterator_category<Itr>
是random_access_iterator
做类似如下:
return (delta > end - i)? end : i + delta;
你可以在vec.begin()使用你的迭代器(它)和迭代器之间的“距离”的功能,并将其与向量的大小比较(按大小得到())。
在这种情况下,你的循环应该是这样的:
for (vector<int>::iterator it = vec.begin(); distance(vec.begin(), it) < vec.size(); ++it)
{
// Possibly advance n times here.
}
该Marijn暗示的代码只是稍有不当(如curiousguy指出)。
最后一行的正确的版本是:
bool isPastEnd = it >= vec.end();
我建议你看一看Boost.Range 。
这可能是使用更安全。
这也将是C ++ 0x中。
container.end() - 元素刚刚过去的端 - 是唯一定义的外部值。
一检查迭代器故障在本质上是超出范围的访问,但这是不是非常有帮助的(特别是作为默认行为是结束程序)。
我认为最好的做法是“不这样做” - 无论是检查迭代器(最好的东西包装成一个过滤器)的每一个值,只有在有趣的条目进行操作,或者明确地使用索引
对(INT I = 0;我vec.size()<; I + = 2){...}
你也可以做更多的比较在您的发言:
for( vector<int>::iterator it = vec.begin(); it != vec.end() && it+1 != vec.end(); it+=2 ) {
//manipulate the element through the iterator here
}
我不知道这将如何执行VS 科斯塔斯的建议,但感觉这将是一个小的增量更好。 当然,因为你需要为每一个检查,但它是另一种选择将是一个大的增量相当难以维护。
如果可能的话,我肯定会避免它。 如果你真的需要通过2个值在一个时间递增,则考虑有性病的矢量::对或结构的2个元素的向量。
尽管这个问题是半年,旧,但它仍然可能是有用的提及使用比较运算符>和<检查,如果你重复过去的结束(或迭代回来的时候开始)的容器。 例如:
vector<int> vec;
vec.push_back( 1 );
vec.push_back( 2 );
vector<int>::iterator it = vec.begin();
it+=10; //equivalent to advance( it, 10 )
bool isPastEnd = it > vec.end(); //true
文章来源: What happens if you increment an iterator that is equal to the end iterator of an STL container