4

我有一段代码需要传递一个函数对象(函数式)。我不能使用函数指针,因为我需要存储一些状态变量。假设我有很多状态变量。通过引用传递函数对象可以吗?我只见过按值传递的函数对象。这就是我的代码的样子:

struct FunctionObject {
    double a, b, x, y;
    double operator() (int v, int w) {....}
};

template <class T>
Class MyClass {
     T& func;
     .....
public:
     MyClass(T& func):func(func) {}
     .....
};
4

4 回答 4

5

通过引用传递函数对象很好,但你应该知道许多 C++ 算法复制函数对象,所以如果你需要一个库算法来尊重你的状态,你应该你的函数对象中将它作为引用传递:

struct State {
    double a, b, x, y;
};
struct Function {
    State &state;
    explicit Function(State &state): state(state) {}
    double operator() (int v, int w) {....}
};
State state;
std::...(..., Function(state), ...)

此外,一些库算法(例如transform)要求 C++11 之前的函数对象没有副作用,即没有任何状态;这个要求很少被强制执行,并且在 C++11 中被放宽了。

于 2012-11-14T16:32:30.517 回答
1

这主要取决于您打算如何实例化 FunctionObject(如何创建函数对象)。如果使用引用,则必须确保函数对象比用户 (MyClass) 对象寿命长。

例如:

MyClass* createObject() {
    MyFunction f(...);         // function object created
    return new MyClass(f);     // reference used
                               // function object destroyed => reference invalid
}

不正确,因为返回的对象具有对已破坏(无效)函数的引用。

由于通过引用传递(避免复制小对象)获得的收益很少,因此不值得麻烦(检查对象生命周期)和疏忽风险(错误)

于 2012-11-14T16:36:14.197 回答
0

合成器是正确的,但是...

  • 大多数情况下,您稍后会在代码中调用函数对象,因此您需要确保您在 MyClass 中提供的引用仍在范围内
  • 所以最后因为你需要将函数对象保存在堆中而不是堆栈中,你必须创建一个指向它的指针......所以我建议使用指针......
于 2012-11-14T16:34:23.673 回答
0

函数对象是对象。您可以通过引用传递它们,并且可以存储对它们的引用,但要遵守通常的生命周期问题。但是,其中的算法std::可以随时复制其函数对象,因此任何存储的状态都可能是陈旧的,因此最好将函数对象编写为指针或对其状态的引用的包装器。

于 2012-11-14T16:34:30.717 回答