0
#include <iostream> 
#include <boost/bind.hpp>

struct FCall3Templ {

  template<typename ARG1, typename ARG2>
  ARG1 operator()(ARG1 arg1, ARG2 arg2) {
    return arg1+arg2;
  }
};
int main() {
  boost::bind<int>(FCall3Templ(), 45, 56)(); // call 1
  boost::bind<double>(FCall3Templ(), 45.0, 56.0)(); // call 2
  return 0;
}

ここにあるのと同じコードを投稿しています

私はメタプログラミング、boost::bind、および演算子のオーバーロードに比較的慣れていませんが、コードの一部でこのコードが何をするのか理解できず、次の質問があります。

  • operator()その演算子のラベルを指定せずに使用するのはなぜですか? オーバーロード/定義とは何ですか?
  • での割り当てを使用して、2 つの呼び出しによって返された値をキャッチして保存する方法を教えてT var = ?ください。
  • ()両方の呼び出しで最後が空であるという事実はどういう意味ですか? オペレーターへの電話ですか?では、このテクニック/オペレーターの名前は何ですか?
  • メソッドだけを使用するのではなく、このようにオーバーロードする演算子を使用するのはなぜですか?

ありがとう。

4

2 に答える 2

3

まず、型FCall3Templはファンクターであり、2 つのパラメーターoperator()は、インスタンスを作成して次のように「呼び出す」ことができることを意味します。

FCall3Templ f; // instantiate it
int i = f(45, 56); // call it, sums the numbers and returns the result

次に、boost::bindパラメーターの数が少ない別の呼び出し可能なオブジェクトを作成するために使用できます。この場合:

boost::bind<int>(FCall3Templ(), 45, 56);

インスタンスを取り、FCall3Templパラメーターなしで呼び出すことができるファンクターを作成します。これは、呼び出しと同じことを行いますf(45, 56)。つまり、ファンクターを 2 つの引数値に「バインド」します。最後の行は同等ですが、まったく同じではありません。

boost::bind<int>(f, 45, 56);

他の関数と同じように、戻り値を変数に代入して値を取得します。

int n = boost::bind<int>(FCall3Templ(), 45, 56);

最後に、ここでそのようなファンクターの一時的なインスタンスを呼び出します。

boost::bind<int>(FCall3Templ(), 45, 56)();

ここで、パラメーターなしのファンクターを呼び出している最終的な()意味は、次のように表現するとより明確になります (テストされていません)。

boost::function<int()> f2 = boost::bind<int>(FCall3Templ(), 45, 56);
int n = f2();
于 2012-08-15T21:13:49.250 に答える
3

あなたの質問に順番に答えてください:

1)operator()()オブジェクトの演算子です。たとえば、std::lessoperator()の定義を見ると、 2 つの引数を取り、比較を行い、結果を返すように定義されています。これにより、次のように書くことができます

  bool foo(int a, int b)
    {
       std::less<int> compare;
       return compare(int a, int b);
    }

2) この場合、通常どおりにキャッチできます。

int i = boost::bind<int>(FCall3Templ(), 45, 56)(); // call 1     
double d = boost::bind<double>(FCall3Templ(), 45.0, 56.0)(); // call 2    

3)boost::bind関数オブジェクト (operator()定義済みのオブジェクト)、関数ポインター、またはメンバー関数ポインターをオプションで引数と共に取るために使用され、呼び出されたときにバインドされた引数を使用する新しい関数オブジェクト (型を記述するのが難しい) を返します。 (および呼び出し中の可能な引数)。boost::bindのドキュメントを参照してください

この場合、答えは単純に呼び出しboost::bindて、すぐに結果を呼び出すことです。の 2 番目のセットは()、結果を呼び出しています。が呼び出された時点ですべての引数がバインドされていたためboost::bind、追加の引数は必要ありませんでした。

4)そして、その理由は、元の質問がboost::bind正しい関数テンプレートのインスタンス化を自動的に選択する方法を尋ねていたからです。残念ながら、関数ポインタ (テンプレート関数を含む) を使用する場合、boost::bind最初の引数として単一の関数ポインタを渡す必要があり、オーバーロードの解決を実行する方法を認識していないため、オーバーロードの解決を自動的に実行できません。

ただし、単一のファンクターが指定され、その関数がテンプレート化されたメンバー関数operator()またはオーバーロードoperator ()された を定義している場合、呼び出されたときにオーバーロードの解決を実行できます。

于 2012-08-15T21:21:28.620 に答える