c ++从vector中删除自定义对象:std :: remove_if':找不到匹配的重载函数

时间:2016-12-20 01:14:44

标签: c++ c++11 vector

在我的项目中有一个向量

 std::vector<std::shared_ptr<MovingEntity>>gameObjects;

我想删除符合条件的元素。

删除元素的方法:

void GameWorld::catchBees()
{
    auto q = std::remove_if(bees.begin(), bees.end(), beeToClose);
    bees.erase(q);
}

方法beeToClose:

bool GameWorld::beeToClose( const MovingEntity & bee)
{
    std::shared_ptr<Beekeeper> keeper = std::static_pointer_cast<Beekeeper>(m_beekeeper);
    if (bee.getConstPosition().distanceTo(m_beekeeper->getPosition()) > keeper->getCatchDistance())
    {
        return true;
    }

    return false;
}

当我尝试编译代码时,我遇到了一些我试图理解的错误:

  

&#39; GameWorld :: beeToClose&#39 ;:非标准语法;使用&#39;&amp;&#39;创造一个   指针

不确定为什么会发出此消息

  

&#39; std :: remove_if&#39;:找不到匹配的重载函数

我没有宣布beeToClose对吗?

  

&#39; q&#39;:在初始化之前无法使用SDLFramework

q未初始化,因为:

std::remove_if(bees.begin(), bees.end(), beeToClose);

运行不正确?

如何在满足某些条件时正确地从向量中删除std :: shared_ptr?

2 个答案:

答案 0 :(得分:5)

形成指向成员函数的指针的语法是&ClassName::FunctionName。因此,您需要&GameWorld::beeToClose作为指向beeToClose成员函数的指针。在您的情况下,您应该使用lambda来调用该函数

auto q = std::remove_if(bees.begin(), bees.end(),
                    [&](shared_ptr<MovingEntity> const& bee){ return beeToClose(bee); });

此外,您使用错误的vector::erase重载,您希望删除一系列元素,而不是删除单个元素的元素。

bees.erase(q, bees.end());

答案 1 :(得分:2)

vector包含std::shared_ptr<MovingEntity>元素,因此beeToClose()需要接受const std::shared_ptr<MovingEntity> &参数作为输入,而不是const MovingEntity &参数。此外,beeToClose()似乎是一个访问非静态类成员(m_beekeeper)的非静态类方法,因此您无法直接将beeToClose()传递给{{ 1}}因为它无法访问调用对象的std::remove_if()指针,但您可以将其包装在lambda中以捕获this指针。

试试这个:

this

您也可以考虑将距离计算移至void GameWorld::catchBees() { auto q = std::remove_if(bees.begin(), bees.end(), [this](const const std::shared_ptr<MovingEntity> &bee) { return this->beeToClose(bee); } ); bees.erase(q, bees.end()); } bool GameWorld::beeToClose(const std::shared_ptr<MovingEntity> &bee) { std::shared_ptr<Beekeeper> keeper = std::static_pointer_cast<Beekeeper>(m_beekeeper); return (bee->getConstPosition().distanceTo(m_beekeeper->getPosition()) > keeper->getCatchDistance()); }

Beekeeper