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), ...)

また、一部のライブラリ アルゴリズム (たとえば) では、関数オブジェクトに副作用がない、つまり状態がまったくないtransformC++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 に答える