【问题标题】:C++ iterating through a set [duplicate]C ++迭代一组[重复]
【发布时间】:2011-07-08 08:22:09
【问题描述】:

我最近更改了一些代码以使用集合而不是向量:

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*>]()'

【问题讨论】:

  • 这与是否重复有什么关系?

标签: c++ iterator set std


【解决方案1】:

您需要将您的迭代器声明为set 迭代器:

改变

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

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

【讨论】:

  • 是的,刚刚注意到。现在工作。这仍然是迭代集合的最佳方式吗?
  • 不,不是,尤其是当涉及到 BOOST_FOREACH 时 ;)
  • BOOST_FOREACH 仍然必须使用集合迭代器本身。它只是隐藏了一些样板。
【解决方案2】:

使用 C++11,您可以简单地编写:

    for(auto pos2:toDestroy)

【讨论】:

    【解决方案3】:

    通过集合的迭代将与向量存在时一样工作,因此无需更改代码。

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

    向量、集合或列表的用法也取决于用法:

    • 如果事先知道 b2Body 对象的数量,我会使用向量,这样可以提前保留容量并且不会经常发生新的插入删除,或者如果您需要随机访问向量的元素(没有迭代器)
    • 如果事先不知道元素的数量和/或经常发生插入和删除,我会使用列表
    • 如果我需要遍历元素的有序列表,或者例如,如果我需要应用程序查找某些数据是否已经处理并在集合中,我会使用集合(集合上的查找方法很快)

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

    【讨论】:

    • 我认为它确实必须改变。我按原样收到错误。编辑了原始帖子以包含错误。
    • 迭代器必须来自集合:std::set::iterator pos2;
    【解决方案4】:

    很多时候都值得对模板化容器类型进行类型定义(尤其是在类中使用时)。

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

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

    BodyCont::iterator pos2;
    

    如果您可以将 typedef 设为私有,那么您就知道实现细节不会转义类。如果您需要公开 typedef,那么您就知道您正在泄漏实现细节并且需要了解原因以及是否可以收紧您的设计。

    【讨论】:

      【解决方案5】:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-09-11
        • 2020-05-04
        • 2019-09-29
        • 2012-07-03
        • 1970-01-01
        相关资源
        最近更新 更多