Таким образом, вот отрывок моего кода.
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;
}
}
Я получаю следующую ошибку при компиляции:
RoutingProtocolImpl.cc:368: error: argument of type bool (RoutingProtocolImpl::)(RoutingProtocolImpl::dv_entry*)' does not match
bool (RoutingProtocolImpl::)(RoutingProtocolImpl::dv_entry)'
Проблема в том, что это: bool RoutingProtocolImpl :: hasInfCost (...)
является нестатической функцией-членом .
Для вызова требуется экземпляр класса, ala: obj-> hasInfCost (...)
. Однако remove_if
не заботится и пытается вызвать его как hasInfCost (...)
. Они несовместимы.
Что вы можете сделать, так это сделать его static
:
static bool RoutingProtocolImpl :: hasInfCost (RoutingProtocolImpl :: dv_entry * entry)
Для этого больше не требуется экземпляр класса для вызова. (У него нет переменных-членов, нет указателя this
и т. Д.). Это можно рассматривать как «нормальную» функцию.
Ваш предикат RoutingProtocolImpl :: hasInfoCost ()
- это функция-член. Алгоритмы STL глупы в том смысле, что они могут работать только с вещами, которые кажутся обычными функциями. Все алгоритмы STL, которые принимают операцию или предикат в качестве параметра, вызывают их как функцию:
op();
Это отлично работает для объектов функций, указателей на обычные функции и указателей на статические члены.В случае функций-членов ссылочных объектов (объекты, созданные в стеке во внешней области алгоритма) или функций-членов указателей на объекты, функция принимает объект, который будет вызван:
obj.mf(); // reference member function
pobj->mf(); // pointer member function
Теперь, чтобы решить проблему, у вас есть количество вариантов.
Преобразование функции-члена в свободную функцию. Если функция должна работать в контексте какого-либо объекта, то этот объект должен быть передан как дополнительный параметр:
bool hasInfCost(RoutingProtocolImpl::dv_entry *entry,
const RoutingProtocolImpl& o);
Затем, когда вы передадите эту функцию как ссылку на алгоритм STL, вам придется связать параметр объекта:
for_each(cont.begin(), cont.end(),
bind2nd(hasInfoCost, RoutingProtocolImpl());
Измените функцию-член, чтобы она была статической функцией-членом. Затем вы можете передать ссылку на него с помощью RoutingProtocolImpl :: hasInfoCost
. Было бы бессмысленно заставлять функцию принимать дополнительный параметр типа инкапсулирующего класса. Если он должен работать в контексте объекта, он не должен быть статическим: либо преобразовать его в свободную функцию (привязанную к ограничениям видимости RoutingProtocolImpl
, тем самым способствуя разделению в вашем коде); или воспользуйтесь подходом связующего и адаптера.
Используйте связыватель и адаптер из STL, чтобы адаптировать свою функцию-член к чему-то, с чем могут работать алгоритмы STL:
dv.erase(remove_if(dv.begin(), dv.end(),
bind1st(mem_fun(&RoutingProtocolImpl::hasInfCost),
this)),
dv.end());
Этот вариант, возможно, является наиболее гибким из всех. Вам не нужно ничего менять в вашем коде, кроме вызова алгоритма. Единственный недостаток состоит в том, что вызов алгоритма теперь будет выглядеть непонятным для непосвященных.
Если вы выберете этот путь, убедитесь, что вы правильно поняли константную корректность: если функция-член не нуждается в изменении объекта, отметьте ее как константную функцию. Таким образом, вы сможете вызывать его с помощью временных и константных объектов, которые вы передаете алгоритмам.