Pins
Pins

Reputation: 217

Using a std::remove_if for vector of non-pointer types

I have a vector of objects :

std::vector<QueuedMessage> _messages;

And trying to remove all objects with erase-remove idiom:

void MessageQueue::removeFromQueue(){
    _messages.erase(std::remove_if(_messages.begin(),_messages.end(),wasMessageSend),_messages.end());
}

My compare function:

bool MessageQueue::wasMessageSend(const QueuedMessage& mess){

            return mess.canSendMessage();
        }

And compare function inside the objects class:

bool QueuedMessage::canSendMessage() const{
    return (SDL_GetTicks() >= startTick);
}

However, I receive this error:

error: must use '.*' or '->*' to call pointer-to-member function in '((__gnu_cxx::__ops::_Iter_pred<bool (MessageQueue::*)(const QueuedMessage&)>*)this)->__gnu_cxx::__ops::_Iter_pred<bool (MessageQueue::*)(const QueuedMessage&)>::_M_pred (...)', e.g. '(... ->* ((__gnu_cxx::__ops::_Iter_pred<bool (MessageQueue::*)(const QueuedMessage&)>*)this)->__gnu_cxx::__ops::_Iter_pred<bool (MessageQueue::*)(const QueuedMessage&)>::_M_pred) (...)'|

Is it a problem that I´m not using a vector of pointers? Or am I missing something? Thanks.

Upvotes: 1

Views: 319

Answers (2)

songyuanyao
songyuanyao

Reputation: 172914

The predicate passed to std::remove_if is supposed to be a unary predicate with signature like bool pred(const Type &a);. That means it will be invoked with the element as the argument. But wasMessageSend is a member function so, besides the argument, it also needs an instance to be invoked on. So it can't be used with remove_if directly.

You can use lambda (since C++11) with it like:

_messages.erase(std::remove_if(
    _messages.begin(),
    _messages.end(),
    [this](const QueuedMessage& q) {
        return wasMessageSend(q);
    }
));

Upvotes: 3

A.S.H
A.S.H

Reputation: 29332

Since wasMessageSend is a member function of your class MessageQueue, you need to "bind it" to an object (in this case, this) using std::bind

void MessageQueue::removeFromQueue(){
_messages.erase(std::remove_if(_messages.begin(),_messages.end(),
    std::bind(&MessageQueue::wasMessageSend, this, std::placeholders::_1), // bind this
    std::_messages.end());
}

Of course, this is not the only way, you may for example define a lambda predicate on the spot... but this method shows how to use a member function as a predicate.

Upvotes: 1

Related Questions