Search code examples
c++oopcollision-detectionerase-remove-idiom

C++ Erase-remove idiom with object


Edit: @Holt helped me, the solution is to pass an instance of Engine if hasCollided is non-static:

std::bind(&Engine::hasCollided, this, ball, _1);

I have a function which returns true or false whether a brick is hit by a ball.

I want to erase a brick which was hit from the vector. I managed to get the idiom working with simple vector of numbers and a bool function, but I get strange errors when I try the same with vector of objects.

Private members:

Ball ball;
std::vector<Brick> bricks;

Collision check:

bool Engine::hasCollided(Ball& object1, Brick& object2)
{
    //do some checks
    return 1;
}

My attempt:

using namespace std::placeholders;

auto f = std::bind(hasCollided, ball, _1);
bricks.erase(std::remove_if(bricks.begin(), bricks.end(), f), bricks.end());

Error happens in the predefined_ops.h right here:

template<typename _Iterator>
    bool
    operator()(_Iterator __it)
    { return bool(_M_pred(*__it)); }
    };

And the compiler spits out 92 errors. Please help me fix that

Example error:

required from '_ForwardIterator std::__remove_if(_ForwardIterator, _ForwardIterator, _Predicate) [with _ForwardIterator = __gnu_cxx::__normal_iterator<Game::Brick*, std::vector<Game::Brick> >; _Predicate = __gnu_cxx::__ops::_Iter_pred<std::_Bind<std::_Mem_fn<bool (Game::Engine::*)(Game::Ball&, Game::Brick&)>(Game::Ball, std::_Placeholder<1>)> >]'


Solution

  • Since hasCollided is a not a static function, you need to pass an instance of Engine to std::bind.

    Assuming you are doing the erase/remove inside a method of Engine, you can do the following:

    auto f = std::bind(&Engine::hasCollided, this, ball, _1);
    //                                       ^^^^