Search code examples
c++stlstl-algorithm

Passing a member function with two parameters to C++ STL algorithm stable_partition


I have member functions as follows

class foo 
{
    public:
        ...
        bool isNotEqualId(const Agent&, const int);
        std::vector<Agent> foo::extractAgents(int id);
    private:
        std::vector<Agent> agents;
}

The function definition is below:

bool foo::isNotEqualId(const Agent& agent, const int id)
{
    return (agent.groupId != id);
} 

Now, within foo, I am partitioning agents given the agent ID, in order to extract them given another parameter later on.

std::vector<Agent>& foo::extractAgents(int id)
{
    std::vector<Agent>::iterator iter = std::stable_partition(agents.begin(), agents.end(), &foo::isNotEqualId(id));

    // Partition to find agents that need to be removed
    std::vector<Agent>::iterator extractedGroupiter = std::stable_partition(iter, agents.end(), keepAgent);
    // Create a vector with the agents that need to be removed
    std::vector<Agent> extractedGroup(extractedGroupiter, agents.end());
    // Erase them from the agents vector
        agents.erase(extractedGroupiter, agents.end());
        return extractedGroup;
}

using std::stable_partition used to work when used with functions that had a fixed group value, such as

bool isNotGroup0(const Agent& a)
{
    return a.groupId != 0;
}

However, now I want to use a member function that takes in two parameters, so the group ID can be a parameter. stable_partition takes in a unary predicate which is causing me the issue. I've tried using std::bind2nd with std::mem_fun in order to bind the 2nd parameter when passing it to stable_partition, but it results in errors with mem_fun having no instance of the overloaded function.

I've also tried a functor solution such as here, which suggests using a std::binary_function, however it understandably results in an error of term does not evaluate to a function taking 1 arguments. I'm using VS2010. Any Pointers?


Solution

  • Since you're using Visual Studio 2010, and I don't know if lambdas are available in that version, use a function object:

    struct AgentFunctor
    {
       int id_;
       AgentFunctor(int id) : id_(id) {}
       bool operator()(const Agent& agent) const
       { return agent.groupId != id_; }
    };
    //...
    AgentFunctor af(id);
    std::vector<Agent>::iterator iter = std::stable_partition(agents.begin(), agents.end(), af);