简体   繁体   中英

c++ remove custom object from vector : std::remove_if': no matching overloaded function found

In my project there is a vector

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

Which I want to delete elements from if they meet the criteria.

Method to delete elements:

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

Method 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;
}

When I try to compile the code I get some errors which I tried to understand:

'GameWorld::beeToClose': non-standard syntax; use '&' to create a pointer

Not sure why this message is given

'std::remove_if': no matching overloaded function found

I did not declare beeToClose right?

'q': cannot be used before it is initialized SDLFramework

q is not initialized because:

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

does not run correct?

How can I remove a std::shared_ptr correctly from a vector correctly when meeting some criteria?

The syntax for forming a pointer to member function is &ClassName::FunctionName . So you need &GameWorld::beeToClose for a pointer to the beeToClose member function. In your case, you should use a lambda from which you call that function

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

Also, you're using the wrong vector::erase overload, you want the one that erases a range of elements, not the one that erases a single element.

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

The vector contains std::shared_ptr<MovingEntity> elements, so beeToClose() needs to accept a const std::shared_ptr<MovingEntity> & parameter as input, not a const MovingEntity & parameter. Also, beeToClose() appears to be a non-static class method that accesses a non-static class member ( m_beekeeper ), so you can't just pass beeToClose() directly to std::remove_if() as it does not have access to the calling object's this pointer, but you can wrap it in a lambda to capture the this pointer.

Try 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());
}

You might also consider moving the distance calculation into Beekeeper instead:

bool GameWorld::beeToClose(const std::shared_ptr<MovingEntity> &bee)
{
    std::shared_ptr<Beekeeper> keeper = std::static_pointer_cast<Beekeeper>(m_beekeeper);
    return !keeper->isInCatchDistance(bee);
}

bool Beekeeper::isInCatchDistance(const std::shared_ptr<MovingEntity> &bee)
{
    return (bee->getConstPosition().distanceTo(getPosition()) <= getCatchDistance());
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM