将函数传递给remove_if时出现C ++编译错误

问题描述 投票:6回答:2

所以这是我的代码片段。


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)'
c++ compiler-errors function-pointers
2个回答
5
投票

问题在于:bool RoutingProtocolImpl::hasInfCost(...)是非静态成员函数。

它需要一个类的实例来调用,ala:obj->hasInfCost(...)。然而,remove_if不关心并试图称之为hasInfCost(...)。这些是不相容的。

你能做的就是把它变成static

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


11
投票

The Problem

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

op();

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

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

现在,要解决此问题,您有许多选择。

The Free Function Option

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

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

然后,当您将此函数作为STL算法的引用传递时,您将必须绑定object参数:

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

The Static Member Option

更改成员函数,使其成为静态成员函数。然后,您可以使用RoutingProtocolImpl::hasInfoCost传递对它的引用。让函数接受封装类'类型的额外参数是没有意义的。如果它需要在一个对象的上下文中工作,那么它不应该是静态的:要么将它转换为自由函数(绑定到RoutingProtocolImpl可见性约束,从而促进代码中的解耦);或采取粘合剂和适配器方法。

The Binder and Adapter Option

使用STL中的绑定器和适配器使您的成员函数适应STL算法可以使用的内容:

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

这个选项可以说是所有人中最灵活的选择。除了调用算法之外,您无需更改代码中的任何内容。唯一的缺点是,对于没有经验的人来说,对算法的调用现在看起来有点模糊。

如果选择此路径,请确保正确的const正确性:如果成员函数不需要更改对象,则将其标记为const函数。这样,您就可以使用传递给算法的临时和const对象来调用它。

© www.soinside.com 2019 - 2024. All rights reserved.