C++ C++;将函数传递到remove_if时发生编译错误

C++ C++;将函数传递到remove_if时发生编译错误,c++,compiler-errors,function-pointers,C++,Compiler Errors,Function Pointers,这是我的一段代码 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

这是我的一段代码


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\u如果
不关心,则尝试将其称为
hasInfCost(…)
。这些是不相容的

您可以做的是将其设置为静态:

static bool RoutingProtocolImpl::hasInfCost(RoutingProtocolImpl::dv_entry*entry)
这不再需要调用类的实例。(它没有成员变量,没有
这个
指针等)。可以将其视为“正常”功能。

问题 谓词
RoutingProtocolImpl::hasInfoCost()
是一个成员函数。STL算法很愚蠢,因为它们只能处理感觉像常规函数的东西。所有以操作或谓词为参数的STL算法都像函数一样调用它们:

op();
这适用于函数对象、指向常规函数的指针和指向静态成员的指针。对于引用对象的成员函数(在算法外部作用域的堆栈上创建的对象)或指向对象的指针的成员函数,该函数将调用一个对象:

obj.mf();   // reference member function
pobj->mf(); // pointer member function
现在,要解决这个问题,你有很多选择

自由函数选项 将成员函数转换为自由函数。如果函数需要在某个对象的上下文中工作,则将该对象作为额外参数传递:

bool hasInfCost(RoutingProtocolImpl::dv_entry *entry,
                const RoutingProtocolImpl& o);
for_each(cont.begin(), cont.end(),
         bind2nd(hasInfoCost, RoutingProtocolImpl());
然后,当您将此函数作为STL算法的引用传递时,必须绑定对象参数:

bool hasInfCost(RoutingProtocolImpl::dv_entry *entry,
                const RoutingProtocolImpl& o);
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());
这一选项可以说是所有选项中最灵活的选项。除了对算法的调用,您不需要更改代码中的任何内容。唯一的缺点是,对算法的调用对于未初始化的人来说现在看起来有些模糊


如果选择此路径,请确保常量正确:如果成员函数不需要更改对象,请将其标记为常量函数。通过这种方式,您将能够使用传递给算法的临时和常量对象调用它。

您使用的
free
让我害怕。:)你为什么不使用
new
delete
?是的,GMan是这么说的。您知道吗,对于
entry->link\u cost!=无限成本
?(或者,如果你在其他地方有指针的副本,那么其他地方的每个
条目->link\u cost==INFINITY\u cost
)都会出现悬空指针,你为什么不使用智能指针呢?