C++遍历一个集合

5

我最近将一些代码从vector改为了set:

std::set<b2Body *>toDestroy;
//std::vector<b2Body *>toDestroy;

但现在我不确定如何迭代集合以查找对象。这是我的代码:

std::vector<b2Body *>::iterator pos2;
    for(pos2 = toDestroy.begin(); pos2 != toDestroy.end(); ++pos2) {
        b2Body *body = *pos2;     
        if (body->GetUserData() != NULL) {
            CCSprite *sprite = (CCSprite *) body->GetUserData();
            [self removeChild:sprite cleanup:YES];
        }
        _world->DestroyBody(body);
    }

现在toDestroy是一个集合,那么现在的等价物是什么?我来自Objective-C,正在学习C++的最佳实践。
编辑:添加我收到的错误信息:
error: no match for 'operator=' in 'pos2 = toDestroy. std::set<_Key, _Compare, _Alloc>::begin [with _Key = b2Body*, _Compare = std::less<b2Body*>, _Alloc = std::allocator<b2Body*>]()'

这与它是否是重复项有什么关系? - Kristopher Johnson
5个回答

5
你需要将迭代器声明为set迭代器:
更改为:
std::vector<b2Body *>::iterator pos2;

为了

std::set<b2Body *>::iterator pos2;

是的,刚刚注意到了。现在可以工作了。这仍然是遍历集合的最佳方式吗? - sol
不是的,特别是当涉及到BOOST_FOREACH时;) - BatchyX
1
BOOST_FOREACH 仍然需要使用 set 迭代器本身。它只是隐藏了一些样板代码。 - Peter

1
使用C++11,你可以简单地写成:

    for(auto pos2:toDestroy)

0
很多时候,值得为模板容器类型进行类型定义(尤其是在类内使用时)。
typedef std::set<b2Body *>   BodyCont;
//typedef std::vector<b2Body *>   BodyCont;
BodyCont                toDestroy;

那么你的其他代码就不需要修改:

BodyCont::iterator pos2;

如果您可以将typedef设置为私有,则知道实现细节不会逃离类。如果您需要将typedef设置为公共,则知道您正在泄漏实现细节,并且需要了解为什么以及是否可以加强设计。

0
自C++11起,在迭代容器时,您应使用“auto”来声明迭代器。 在您的情况下,“for”行可以写成这样: for(auto pos2 = toDestroy.begin(); pos2 != toDestroy.end(); ++pos2)

0

在遍历集合时,它的工作方式与向量相同,因此无需更改代码。

我会注意DestroyBody中发生了什么(调用是否从向量或集合中删除元素,使迭代器无效?)

另外,使用向量、集合或列表取决于使用情况:

  • 如果事先知道b2Body对象的数量,因此可以预先保留容量,并且不经常进行新插入/删除操作,或者如果需要随机访问向量的元素,则应使用向量
  • 如果元素数量事先未知和/或插入和删除经常发生,则应使用列表
  • 如果需要遍历有序元素列表,或者例如需要应用程序查找某些数据是否已经被处理并位于集合中(集合上的查找方法很快),则应使用集合

我认为,在这里最适合的容器是列表(并且迭代代码仍然不需要更改)。


我认为它必须被更改。按原样会出现错误。编辑了原帖以包括错误信息。 - sol
迭代器必须来自于集合:std::set<b2Body*>::iterator pos2; - Paolo Brandoli

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