为什么C++仿函数优于具有命名方法的对象?

zen*_*nna 7 c++ functor function-object

我最近对仿函数很兴奋,并且一直在使用它们.然后情况出现了,我需要我的仿函数执行两个不同的操作,我想到为我的仿函数添加另一个方法(不重载()运算符).这是不是不好的做法我不确定(也许你可以告诉我),但它让我思考为什么我首先使用仿函数而不仅仅是对象.所以我的问题是:

有没有什么特别的重载()运算符或者它是否比使用普通的命名方法更具语法吸引力?

更新:

首先,我知道为什么函子可能比其他问题中解释的函数指针更可取.我想知道为什么它们可以优于具有命名方法的对象.

其次,至于我何时想要使用另一个可能命名的函子方法的例子:基本上我有两个函数,一个计算一个叫做图形分区的模块性的东西compute_modularity(),另一个用于计算一些变化后的模块化增益分区compute_modularity_gain().我以为我可以将这些函数作为同一仿函数的一部分传递给优化算法,并将增益作为命名函数.我不只是传递了两个函子到算法,其原因是,我想执行这一compute_modularity_gain()只与使用一起选择compute_modularity(),而不是另一个函子如compute_stability()(应该仅被使用compute_stability_gain().换句话说,增益功能必须紧密加上它的兄弟功能.如果还有其他方法我可以执行这个约束,那么请告诉我.

Bil*_*eal 6

重载的原因operator()是使函子具有与函数指针相同的调用语义 - 事实上,如果你愿意,你可以使用函数指针.

重载有几个原因operator()而不是使用函数 - 但最重要的是编译器很少在使用函数指针时优化间接函数调用,但它们几乎总是优化掉operator()调用 - 这是为什么std::sort通常节拍std::qsort.

这有很多复杂的原因,但它真正归结为大多数(没有?)编译器实现了删除函数指针调用的优化,这在现代硬件上很昂贵.

然后出现了我需要我的仿函数执行两个不同操作的情况

然后它不再是一个算符.要么传递两个仿函数来做你想要的,要么定义一个模板方法类.(您也可以使用mixins在C++中实现模板方法模式而不需要运行时开销 - 但维基百科文章没有涵盖这一点)(注意:与C++模板不同,但如果你去了C++模板可能会涉及到AOP路线)


xDD*_*xDD 0

函子唯一的特别之处在于它们可以像函数一样使用。然而,函子也可以通过其构造函数注入信息。

您可能还想研究 std::function (如果您的编译器尚不支持,则使用 boost::function ),它可用于调整具有匹配调用签名的任何类型的对象。

std::bind 或 boost::bind 允许您将具体参数与函数的参数关联起来,这与通过仿函数的构造函数传递它们具有相同的效果。您甚至可以使用 bind 提供指向成员函数的 this 指针,以便可以像普通函子一样调用它们,而无需显式指定对象。