函数对象应该是函数实参还是它的引用?

Should function object be an function argument or its reference?

本文关键字:函数 引用 实参 对象      更新时间:2023-10-16

我用下面的例子来说明我的问题:

#include <boost/graph/adjacency_list.hpp>
#include <iostream>
#include <algorithm>

class TestOperator
{
public:
    TestOperator(float k):k_(k){};
    ~TestOperator() {};
    float operator() (float m, float s)
    {
        return (1-k_)*m+k_*m*0.0078*s;
    }
private:
    float k_;
};
template<typename Operator>
void perform(Operator fun)
{
    int value;
    value = fun(3.1f,2.5f);
}
template<typename Operator>
void perform2(Operator &fun)
{
    int value;
    value = fun(3.1f,2.5f);
}

int main()
{
    TestOperator myOperator(0.1f);
    perform(myOperator);

    perform2(myOperator);
   return 0;
}

perform中我们使用函数对象作为函数参数,而在perform2中我们使用函数对象引用作为函数参数。在关于函数对象的教程中,前者的用法占主导地位,就像本教程中的函数对象一样。那么我的问题是:为什么不使用函数对象引用?对我来说,这更好。什么好主意吗?

结构中有成员的函数对象(或functors)在按值传递时将被复制,而在按引用传递时不被复制。

在您的示例中,成员k_将通过引用调用"存活",如在perform2中。如果由于某种原因在函子中保留了信息而没有初始化,这可能会产生奇怪的副作用。

可以使用引用传递方法从一次使用到下一次使用来收集和保留函子内的信息。

如果按值传递,使用的副本将在返回时消失,并且调用之间的信息丢失。

换句话说,原来的函子myOperator没有被perform改变,但被perform2改变了。

可以提供const myOperator来执行,但不能像声明的那样提供perform2。如果将perform2声明为接受const &,它将无法编译,因为函数函数中的函数不是const(不能保证不改变函数函数中的内容)。

哪个"更好"是未知的。在某些情况下,一个比另一个更适用,复制更"安全",更广泛适用,如果理论上较慢的话。

我的指导方针:

一般使用Operator fun

仅当fun的数据不能从operaor()的一次调用复制到下一次调用时才使用Operator& fun。例如,如果使用Operator收集它在容器中保存的数据,则必须通过引用传递fun