Ошибка компиляции C++ при передаче функции в remove_if

Таким образом, вот отрывок моего кода.


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 matchbool (RoutingProtocolImpl::)(RoutingProtocolImpl::dv_entry)'
6
задан Matthias 19 September 2018 в 09:59
поделиться

2 ответа

Проблема в том, что это: bool RoutingProtocolImpl :: hasInfCost (...) является нестатической функцией-членом .

Для вызова требуется экземпляр класса, ala: obj-> hasInfCost (...) . Однако remove_if не заботится и пытается вызвать его как hasInfCost (...) . Они несовместимы.

Что вы можете сделать, так это сделать его static :

static bool RoutingProtocolImpl :: hasInfCost (RoutingProtocolImpl :: dv_entry * entry) Для этого больше не требуется экземпляр класса для вызова. (У него нет переменных-членов, нет указателя this и т. Д.). Это можно рассматривать как «нормальную» функцию.

5
ответ дан 8 December 2019 в 14:41
поделиться

Проблема

Ваш предикат 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());

Этот вариант, возможно, является наиболее гибким из всех. Вам не нужно ничего менять в вашем коде, кроме вызова алгоритма. Единственный недостаток состоит в том, что вызов алгоритма теперь будет выглядеть непонятным для непосвященных.

Если вы выберете этот путь, убедитесь, что вы правильно поняли константную корректность: если функция-член не нуждается в изменении объекта, отметьте ее как константную функцию. Таким образом, вы сможете вызывать его с помощью временных и константных объектов, которые вы передаете алгоритмам.

11
ответ дан 8 December 2019 в 14:41
поделиться
Другие вопросы по тегам:

Похожие вопросы: