首页 > 解决方案 > 添加元素后如何停止添加到 std::vector

问题描述

我正在尝试进行 boids 模拟。我目前正在做的是检查 boids 是否在彼此的范围内,如果它们在,则将它们的内存地址添加到std::vector被调用withinSensoryRange者中。这是代码。

struct Boid
{
    float sensoryRadius = 50.0f;
    std::vector<Boid*> withinSensoryRange;
};

std::vector<Boid> boids;

while (true)
{

for (int i = 0; i <  boids.size(); i++)
            for (int j = i; j < boids.size(); j++)
            {
                float distance = sqrtf((boids[i].position.x - boids[j].position.x) * (boids[i].position.x - boids[j].position.x) +
                    (boids[i].position.y - boids[j].position.y) * (boids[i].position.y - boids[j].position.y));

                if (distance > boids[i].sensoryRadius)
                {
                    boids[i].withinSensoryRange.push_back(&boids[j]);
                    boids[j].withinSensoryRange.push_back(&boids[i]);
                }
            }
}

我的问题是,只要它们在范围内,它就会每帧不断地添加到向量中。有没有办法检测它是否已经在向量中,如果是就不要添加它?谢谢。

标签: c++

解决方案


您可以使用std::find来检查容器中是否已存在项目。或者您可以使用包含唯一键的容器,例如std::unordered_set.

警告!!

存储地址时需要非常小心。如果对象移动或超出范围,则地址将变为无效。这实际上是您的示例中可能发生的情况,因为std::vector会在调整大小时移动对象。

解决方案:

  • 关联并存储一些唯一标识符
  • 使用std::unique_ptr( std::vector<std::unique_ptr<Boid>> boids;),这将确保对象不会移动(移动的是智能指针)
  • 制作boidsvector或set const(在构造时对其进行初始化)并确保包含对象(如果有)不会在您通过指针的访问过程中移动。
  • 使用在调整大小时不会使迭代器无效的容器,例如std::list

我尝试以 std::unique_ptr 方式进行操作。当我尝试推回内存地址时它不起作用

withinSensoryRange应该是原始指针的向量:

struct Boid
{
    float sensoryRadius = 50.0f;
    std::vector<Boid*> withinSensoryRange;
};

std::vector<std::unique_ptr<Boid>> boids;

//...

boids[i]->withinSensoryRange.push_back(boids[j].get())

推荐阅读