添加元素后,如何停止添加到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]);
                }
            }
}

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

回答

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

警告!!

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

解决方案:

  • 而是关联并存储一些唯一标识符
  • 使用std::unique_ptr( std::vector<std::unique_ptr<Boid>> boids;),这将确保对象不会移动(移动的是智能指针)
  • make 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())


以上是添加元素后,如何停止添加到std::vector的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>