7

私は次の例を理解しようとしています。これは SOヘルプで以前に投稿されたものと似ていますが (等しくはありません)、boost::bind プレースホルダー引数を理解しています:

#include <boost/bind.hpp>
#include <functional>

struct X {
    int value;
};

int main() {    
    X a = { 1 };
    X b = { 2 };

    boost::bind(std::less<int>(),
        boost::bind(&X::value, _1),
        boost::bind(&X::value, _2))
    (a, b);
}

最も外側のバインド関数が、最初の引数を 2 番目のバインド ( を期待する_1) に渡し、2 番目の引数を 3 番目のバインド ( を期待する_2) に渡す必要があることをどのように認識できるのでしょうか? 私がこれを見る方法は、内側のバインダーが最初に評価されるため、それらは 2 つの単項関数オブジェクトになり、後でオブジェクトのバインダーに渡されるというless<int>ことです。そして、新しく作成された機能オブジェクトが 2 つのオブジェクトで呼び出されるとa、最初のインナー バインドにb移動し、2 番目のインナー バインドに移動します。私が正しければ、_12回使用します。私は間違っているに違いない。問題を明確にするために、もう一度質問を繰り返します。外側のバインダーは、どのプレースホルダーがどの内側のバインダーで使用されたかをどのように認識しますか?

4

1 に答える 1

7

引数はタプル (a,b) にパックされ、ファンクターに渡されます。次に、内部ファンクターが必要なタプル要素を決定します。たとえば、次を試してください。

boost::bind(&X::value, _1)(a,b)
boost::bind(&X::value, _2)(a,b)

より一般的には、定数/参照/プレースホルダーであるかどうかに関係なく、すべての値は、引数タプルを取り、値を返すファンクターとして表されます。

bind(f, 10)(a) // still functor which discards arguments

さて、これが bind のやり方であると 100% 確信しているわけではありません。ただし、これはフェニックスがその機能を実装する方法です。バインド/ラムダ実装のメカニズムを理解しようとしている場合は、phoenix を見てください。非常に拡張性が高く、優れたドキュメントがあります。

于 2010-09-20T18:51:28.143 に答える