0

次の関数をC++で実装できますか?myInstanceインスタンスに変数を含めるのではなく、コールバックメソッドが呼び出されるまで変数を指定しないでおく必要がありboost::bindます。

MyClass *myInstance;

void call(/* boost::mem_fn */ callback)
{
    // Somewhere in this function, the operator()() method
    // is called on the callback instance

    callback(myInstance);
}

call(boost::mem_fn(&MyClass::myMethod));

boost::mem_fnこれは特定のオブジェクトを返す関数であることは理解していますが、そのタイプはわかりません。ドキュメントには、リターンタイプとして未指定と記載されています。コンストラクターの1つがこのboost::bind型をパラメーターとして受け取りますが、その実装で実際の宣言を見つけることができません。また、この特定のタイプの独自のインスタンスを保存することも許可されていますか、それともこれは厳密にブースト関数で使用するためのものですか?

4

3 に答える 3

5

これは、コンパイラが非常に魔法のようなことをしているように見えるケースの1つです。

実際に明確に定義された型がない理由は、bosst :: mem_fnから返される型が、渡される関数のテンプレートパラメーターであると常に想定されているためです。例を示しましょう:

std :: for_eachには、次のような署名があります。

template <class InputIterator, class Function>
Function for_each (InputIterator first, InputIterator last, Function f);

この小さな魔法のスライスには、InputIteratorとFunctionの2つのテンプレートパラメーターがあります。これらは何とでも呼ばれる可能性がありますが、それらに付けられた名前は、実際には、実際のタイプよりも自己文書化された名前です。InputIteratorのタイプは、次のようなものである可能性がありますstd::vector<foo>::iterator。要点は、コンパイラがコンパイル時に「InputIterator」が何であるかを自動的に解決することです。それはあなたのためにこのタイプを理解することができます。

関数についても同じことが言えます。operator()呼び出すことができるもの、つまり、呼び出されるものと互換性のあるバージョンを持っているものを渡す限り、for_each関数が何であるかを知る必要はありません。

つまり、簡単な答えは、call関数にテンプレートパラメータをとらせることです。

template<typename SomeSortOfFunction>
void call(SomeSortOfFunction callback)

次に、コンパイラはSomeSortOfFunction、返されるタイプが何であれ、解決する必要があります。boost::mem_fn

于 2012-11-08T17:42:58.880 に答える
3

の戻りタイプboost::mem_fn指定されていません。Mattのアプローチ(つまり、テンプレートとして渡す)を使用するか、個別のコンパイルが重要な場合は、型消去を使用する必要があります。

MyClass *myInstance;

void call(boost::function<void(MyClass*)> callback)
{
    callback(myInstance);
}

call(boost::mem_fn(&MyClass::myMethod));
于 2012-11-08T17:54:23.147 に答える
1

の戻りタイプは、mem_fn明示的に入力または保存する必要があるものではありません。これは、コンパイル時に引数のタイプを介して生成されます。

ただし、std::function(またはboost::function)を介して保存することはできます。

operator()シグニチャmen_fnは、先頭にクラスへのポインタが付加された元のメソッド引数でconstあり、同じ戻り値の型です。std::functionその署名を使用してを作成するだけで、men_fnタイプを取得して保存できます。

つまり、引数がゼロのメソッドclass fooが返される場合voidは、men_funをに格納してみてくださいstd::function<void(foo *)>

于 2012-11-08T19:05:00.520 に答える