So here's 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;
}
}
I'm getting the following error when compiling:
RoutingProtocolImpl.cc:368: error: argument of type bool (RoutingProtocolImpl::)(RoutingProtocolImpl::dv_entry*)' does not match
bool (RoutingProtocolImpl::)(RoutingProtocolImpl::dv_entry)'
Your predicate RoutingProtocolImpl::hasInfoCost()
is a member function. The STL algorithms are dumb in that they can only work with things that feel like regular functions. All the STL algorithms that take an operation or a predicate as parameter invoke them like a function:
op();
This works fine for function objects, pointers to regular functions and pointers to static members. In the case of member functions of reference objects (objects created on the stack in the algorithm's outer scope) or member functions of pointers to objects the function takes an object to be invoked on:
obj.mf(); // reference member function
pobj->mf(); // pointer member function
Now, to resolve the issue you have a number of options.
Translate the member function to a free function. If the function needs to work in the context of some object then have that object passed as an extra parameter:
bool hasInfCost(RoutingProtocolImpl::dv_entry *entry,
const RoutingProtocolImpl& o);
Then, when you pass this function as a reference to an STL algorithm you will have to bind the object parameter:
for_each(cont.begin(), cont.end(),
bind2nd(hasInfoCost, RoutingProtocolImpl());
Change the member function so it is a static member function. You can then pass a reference to it with RoutingProtocolImpl::hasInfoCost
. It would make no sense to have the function accept an extra parameter of the encapsulating class' type. If it needs to work in the context of an object then it shouldn't be static: either transform it to a free function (bound to the RoutingProtocolImpl
visibility constraints, thus promoting decoupling in your code); or take the binder and adapter approach.
Use a binder and an adapter from the STL to adapt your member function to something the STL algorithms can work with:
dv.erase(remove_if(dv.begin(), dv.end(),
bind1st(mem_fun(&RoutingProtocolImpl::hasInfCost),
this)),
dv.end());
This option is arguably the most flexible option of all. You need not change anything in your code, other than the call to the algorithm. The only drawback is that the call to the algorithm will now look somewhat obscure for the uninitiated.
If you choose this path then make sure you get your const-correctness right: if the member function doesn't need to change the object then mark it as a const function. This way you will be able to invoke it with temporary and const objects that you pass to algorithms.
The problem is that this: bool RoutingProtocolImpl::hasInfCost(...)
is a nonstatic member function.
It requires an instance of the class to invoke on, ala: obj->hasInfCost(...)
. However, remove_if
cares not and tries to call it as hasInfCost(...)
. These 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 invoke. (It has no member variables, no this
pointer, etc.). It can be treated as a "normal" function.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With