是否可以迭代从结尾到开头的向量?
for (vector<my_class>::iterator i = my_vector.end();
i != my_vector.begin(); /* ?! */ ) {
}
Run Code Online (Sandbox Code Playgroud)
或者只有这样的东西才有可能:
for (int i = my_vector.size() - 1; i >= 0; --i) {
}
Run Code Online (Sandbox Code Playgroud) 关于以下代码是否是合法的C++ ,这个问题一直存在争议:
std::list<item*>::iterator i = items.begin();
while (i != items.end())
{
bool isActive = (*i)->update();
if (!isActive)
{
items.erase(i++); // *** Is this undefined behavior? ***
}
else
{
other_code_involving(*i);
++i;
}
}
Run Code Online (Sandbox Code Playgroud)
这里的问题是erase()将使有问题的迭代器无效.如果在i++评估之前发生这种情况,那么这样的增量i在技术上是未定义的行为,即使它似乎与特定的编译器一起使用.辩论的一方面说,在调用函数之前,所有函数参数都已完全评估.另一方说,"唯一的保证是i ++将在下一个语句之前和使用i ++之后发生.无论是在擦除(i ++)之前还是之后都依赖于编译器."
我打开这个问题,希望能够解决这个问题.
请考虑以下情况:
using namespace std;
unordered_map<int, vector<A>> elements;
Run Code Online (Sandbox Code Playgroud)
现在我正在迭代这个无序的地图:
for (auto it = elements.begin(); it != elements.end(); ++it)
Run Code Online (Sandbox Code Playgroud)
在循环内部,我正在形成几个元素elements(当前的一个it指向和更多的元素,不一定是那些在线的那些!).因为每个元素只能是一个集群的一部分,所以我想从地图中删除它们,然后继续下一个元素(即构建下一个集群).
我怎么能这样做并仍然在正确的位置继续迭代?
我在迭代时可以从std :: list中删除元素吗?例如:
std::list<int> lst;
//....
for (std::list<int> itr = lst.begin(); itr != lst.end(); itr++)
{
if (*itr > 10)
lst.remove(*itr);
}
Run Code Online (Sandbox Code Playgroud)
?为什么?
因此,当我们需要从头到尾遍历容器时,我们会写出类似的内容
for (i = v->begin(); i != v->end(); i++)
假设i是容器的迭代器v.
我的问题是"什么保证结束总是指向容器中最后一个元素的一个?" STL如何确保这种行为,这种情况是否有可能不正确?
我有一份清单std::list<T *> *l;.此列表不为空且具有一些值.我的问题是如何正确访问项目?我不需要遍历列表.我只想要第一个项目.
std::list<T*>::iterator it = l->begin();
if (it != l->end())
{
// accessing T
int value = (*it)->value(); // Is this safe?
}
Run Code Online (Sandbox Code Playgroud)
或者我也应该检查是否为空?
if (it != l->end() && (*it))
{
// accessing T
int value = (*it)->value();
}
Run Code Online (Sandbox Code Playgroud) 我在一个函数中有一个循环,它从头到尾迭代std::list.
在每个循环中,我执行一些检查,并可能对当前列表条目进行一些操作,在某些情况下,我想从列表中删除它.
现在,正如预期的那样,我的迭代器变得无效.
std::list如果只有指向要删除的元素的迭代器,是否可以从中删除元素?我有大量的函数需要迭代器来列出元素,并且必须将拥有权传递list给它们中的每一个都是非常不便的.
标准是否明确禁止在其中修改容器std::for_each?
更具体地说,在std::list修改列表时,迭代器不会失效.因此,以下代码有效:
std::list<int> list;
list.push_front(5);
list.push_front(10);
auto it = list.end();
it--; // point to 5
std::for_each(list.begin(), list.end(), [&](int i){
/* the line below will remove the last element in the list;
* list will have only one element (the currently processed one);
* list.end() is not invalidated and we exit for_each() */
list.erase(it);
});
Run Code Online (Sandbox Code Playgroud)
这绝对是一个糟糕的代码.但这是合法的吗?
可能重复:
在基于范围的for循环内擦除容器中的元素
与此类似,您可以在使用新for( auto item : list )语法迭代STL列表时从STL列表中删除吗?
这是一个完整的例子(崩溃!)
#include <list>
using namespace std ;
int main()
{
list<int> li;
li.push_back( 4 ) ;
li.push_back( 5 ) ;
li.push_back( 6 ) ;
for( auto num : li )
{
if( num == 5 )
li.remove( num ) ;
else
printf( "%d\n", num ) ;
}
}
Run Code Online (Sandbox Code Playgroud)