迭代器有效性,在 std::set 中调用擦除()之后
std::set 中的擦除调用会使迭代器无效吗?正如我从最后一行开始的第 5 行以下所做的那样……? 如果是的话,从集合中删除所有元素的更好方法是什么
class classA
{
public:
classA(){};
~classA(){};
};
struct structB
{
};
typedef std::set <classA*, structB> SETTYPE;
typedef std::map <int, SETTYPE>MAPTYPE;
int __cdecl wmain (int argc, wchar_t* pArgs[])
{
MAPTYPE mapObj;
/*
...
.. Some Operation Here
...
*/
for (MAPTYPE::iterator itr1=mapObj.begin(); itr1!=mapObj.end(); itr1++)
{
SETTYPE li=(*itr1).second;
for (SETTYPE::iterator itr2=li.begin();itr2!=li.end();itr2++)
{
classA *lt=(classA*)(*itr2);
li.erase(itr2);
delete lt; // Does it invalidate Iterator ?
}
}
}
Do erase call in std::set invalidate iterator ? As i have done below 5th from last line..?
if yes what is better way to erase all elements from set
class classA
{
public:
classA(){};
~classA(){};
};
struct structB
{
};
typedef std::set <classA*, structB> SETTYPE;
typedef std::map <int, SETTYPE>MAPTYPE;
int __cdecl wmain (int argc, wchar_t* pArgs[])
{
MAPTYPE mapObj;
/*
...
.. Some Operation Here
...
*/
for (MAPTYPE::iterator itr1=mapObj.begin(); itr1!=mapObj.end(); itr1++)
{
SETTYPE li=(*itr1).second;
for (SETTYPE::iterator itr2=li.begin();itr2!=li.end();itr2++)
{
classA *lt=(classA*)(*itr2);
li.erase(itr2);
delete lt; // Does it invalidate Iterator ?
}
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
来自标准 23.1.2
编辑
在您的情况下 itr2 在擦除后无效,因此增加它会导致未定义的行为。在这种情况下,您可以遵循 reko_t 建议,一般来说,您可以尝试以下操作:
这将在之前从集合中删除其先前的值之前增加迭代器。
顺便提一句。 itr2 不会被
delete lt;
失效,而是被li.erase(itr2);
失效From standard 23.1.2
EDIT
In your case itr2 is invalidated after erasing so incrementing it causes undefined behaviour. In this case you can follow reko_t advice, in general, you can try this:
which will increment iterator before removing it's previous value from set.
BTW. itr2 is not invalidated by
delete lt;
, but byli.erase(itr2);
删除就ok了
问题是您擦除了 - 从而使 -
itr2
无效,但将其用于循环迭代。iaw 第一次擦除后,
++itr2
具有未定义的结果。我在这种情况下使用的模式是这样的:
一些非标准 STL impls 已擦除返回下一个迭代器,因此您可以这样做:
但这不是可移植的。
set
很奇怪,尽管在标准实现中,B 将是比较器。The delete is ok.
The problem is that you erase - and thus invalidate -
itr2
, but use it for loop iteration.i.a.w. after the first erase, the
++itr2
has undefined results.The pattern I use in this situation is this:
Some non-standard STL impls have erase return the next iterator, so you could do:
that's not portable, though.
the
set<A*,B>
is strange, though - in a standard impl, B would be the comparator.由于您显然只是删除了集合中的每个元素,因此您可以这样做:
Since you are just apparently deleting every element of the set, you could just do: