C ++ compilation error when passing a function to remove_if

So here is a snippet of my code.

void RoutingProtocolImpl::removeAllInfinity() { dv.erase(std::remove_if(dv.begin(), dv.end(), hasInfCost), dv.end()); } bool RoutingProtocolImpl::hasInfCost(RoutingProtocolImpl::dv_entry *entry) { if (entry->link_cost == INFINITY_COST) { free(entry); return true; } else { return false; } } 

When compiling, I get the following error:

 RoutingProtocolImpl.cc:368: error: argument of type bool (RoutingProtocolImpl::)(RoutingProtocolImpl::dv_entry*)' does not match bool (RoutingProtocolImpl::)(RoutingProtocolImpl::dv_entry)' 
code>

Sorry, I'm kind of like C ++ newb.

+5
c ++ compiler-errors function-pointers
source share
2 answers

The problem is this: bool RoutingProtocolImpl::hasInfCost(...) is a non-static member function.

This requires an instance of the class to call, ala: obj->hasInfCost(...) . However remove_if does not care and tries to call it hasInfCost(...) . They are incompatible.

What you can do is make it static :

static bool RoutingProtocolImpl::hasInfCost(RoutingProtocolImpl::dv_entry *entry) This no longer requires an instance of the class to call. (It has no member variables, no this pointer, etc.). It can be considered as a "normal" function.

+5
source share

Problem

Your predicate RoutingProtocolImpl::hasInfoCost() is a member function. STL algorithms are unthinkable in that they can only work with things that resemble normal functions. All STL algorithms that accept an operation or predicate as a parameter call them as a function:

 op(); 

This works great for function objects, pointers to regular functions, and pointers to static elements. In the case of member functions of reference objects (objects created on the stack in the outer area of ​​the algorithm) or member functions of pointers to objects, the function accepts the object to which it is necessary to call:

 obj.mf(); // reference member function pobj->mf(); // pointer member function 

Now, to solve the problem, you have several options.

Free function option

Translate a member function into a free function. If the function should work in the context of some object, then this object is passed as an additional parameter:

 bool hasInfCost(RoutingProtocolImpl::dv_entry *entry, const RoutingProtocolImpl& o); 

Then, when you pass this function as a reference to the STL algorithm, you will have to bind an object parameter:

 for_each(cont.begin(), cont.end(), bind2nd(hasInfoCost, RoutingProtocolImpl()); 

Static Member Option

Modify the member function so that it is a static member function. You can then pass the link to it using RoutingProtocolImpl::hasInfoCost . It would be pointless if the function accepted an additional parameter of the encapsulating class type. If it is necessary to work in the context of an object, then it should not be static: either convert it to a free function (by RoutingProtocolImpl to the visibility restrictions of RoutingProtocolImpl , thereby contributing to the decoupling of the code); or take a binder and adapter approach.

Binder and adapter option

Use the STL binding and adapter to adapt your member function to something that STL algorithms can work with:

 dv.erase(remove_if(dv.begin(), dv.end(), bind1st(mem_fun(&RoutingProtocolImpl::hasInfCost), this)), dv.end()); 

This option is perhaps the most flexible option for everyone. You do not need to change anything in the code, except for calling the algorithm. The only drawback is that calling the algorithm will now be somewhat obscure to the uninitiated.

If you choose this path, make sure that you specify the correctness of the constant correctly: if the member function does not need to change the object, mark it as a const function. This way you can call it using temporary and const objects that you pass to the algorithms.

+8
source share

All Articles