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

时间:2015-09-18 21:56:25

标签: c++

我使用以下示例来说明我的问题:

#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中使用函数对象作为函数参数wile,我们使用函数对象引用作为函数参数。在关于函数对象的教程中,前一种用法与本教程function objects一样占主导地位。那我的问题是:为什么不使用函数对象引用?对我来说,它更好。有任何想法吗?

2 个答案:

答案 0 :(得分:1)

我的指南:

在大多数情况下使用Operator fun

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

答案 1 :(得分:1)

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

在您的示例中,成员k_将通过引用调用“生存”,如perform2中所示。如果出于某种原因,在仿函数中保留了信息并且没有初始化,则可能会产生奇怪的副作用。

可以使用pass by reference来收集和保留仿函数中从一次使用到下一次使用的信息。

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

换句话说,原始的仿函数myOperator在执行时没有改变,但它被perform2改变了。

你可以提供一个const myOperator来执行,但不能像声明那样执行2。如果你声明perform2是一个const&amp;,它就不会编译,因为函子中的函数不是const(不能保证不改变仿函数中的东西)。

哪个'更好'还不得而知。在某些情况下,一种比另一种更适用,如果理论上较慢,则副本“更安全”并且更广泛适用。