原文:http://www.boost.org/libs/bind/bind.html

c++boost.gif (8819 bytes)

bind.hpp

 

Contents

Purpose

Using bind with functions and function pointers

Using bind with function objects

Using bind with pointers to members

Using nested binds for function composition

Examples

Using bind with standard algorithms

Using bind with Boost.Function

Limitations

Frequently Asked Questions

Why doesn't this compile?

Why does this compile? It should not.

What is the difference between bind(f, ...) and bind<R>(f, ...)?

Does bind work with Windows API functions?

Does bind work with COM methods?

Does bind work with Mac toolbox functions?

Does bind work with extern "C" functions?

Why doesn't bind automatically recognize nonstandard functions?

Troubleshooting

Incorrect number of arguments

The function object cannot be called with the specified arguments

Accessing an argument that does not exist

Inappropriate use of bind(f, ...)

Inappropriate use of bind<R>(f, ...)

Binding a nonstandard function

const in signatures

MSVC specific: using boost::bind;

MSVC specific: class templates shadow function templates

MSVC specific: ... in signatures treated as type

Interface

Synopsis

Common requirements

Common definitions

bind

Additional overloads

Implementation

Files

Dependencies

Number of Arguments

"__stdcall", "__fastcall", and "pascal" Support

visit_each support

Acknowledgements

Purpose

boost::bind は標準ライブラリの関数 std::bind1st および std::bind2nd を汎用化したものである。 関数オブジェクトだけでなく、関数や関数へのポインタ、メンバ関数へのポインタをサポートし、任意の引数を特定の値に束縛したり、入力引数を、もとの順番に関係なく自由な位置に移し替えることができる。 bind が扱うことのできる関数オブジェクトには、特別な条件はない。 特に、標準関数が要求する typedef result_typefirst_argument_type および second_argument_type は必須ではない。

【訳注:このような関数を一般に「バインダ」または「束縛子」と呼ぶ。】

【訳注:「入力引数」とは、bind によって生成された関数オブジェクトを呼び出す時に渡される引数。例えば、bind(f, _1, 5)(x) における x のこと。】

Using bind with functions and function pointers

以下の関数が定義されているとき、

int f(int a, int b)
{
    return a + b;
}

int g(int a, int b, int c)
{
    return a + b + c;
}

bind(f, 1, 2) は "nullary" (無項)、つまり引数をとらない関数オブジェクトを生成する。これを評価すると f(1, 2) を返す。 同様に、bind(g, 1, 2, 3)()g(1, 2, 3) と等価である。

【訳注:"nullary" は boost の造語のようで、「いくつかの邪悪な提案のうち、いちばんマシ」として選ばれたとの記述が compose ライブラリのコメント にある。】

引数のうちいくつかだけを、選択的に束縛することもできる。 例えば、bind(f, _1, 5)(x)f(x, 5) と等価である。 ここで、_1 は「最初の入力引数によって置き換えられる」ことを意味するプレースホルダである。

【訳注:残念ながら、bind(f, _1, 5)(10) のように、入力引数にリテラルを渡すことはできない。詳しくは、Limitations を参照。】

【訳注:ここに lambda_1 との関連を書く、かも。】

比較のため、同じ操作を標準ライブラリのプリミティブを使って書くとこうなる。

std::bind2nd(std::ptr_fun(f), 5)(x);

bindstd::bind1st の機能もカバーしている。

std::bind1st(std::ptr_fun(f), 5)(x);   // f(5, x)
bind(f, 5, _1)(x);                     // f(5, x)

bind は二つ以上の引数を持つ関数を扱うことができる。 また、引数の置き換え機能はより一般化されている。

bind(f, _2, _1)(x, y);                 // f(y, x)

bind(g, _1, 9, _1)(x);                 // g(x, 9, x)

bind(g, _3, _3, _3)(x, y, z);          // g(z, z, z)

bind(g, _1, _1, _1)(x, y, z);          // g(x, x, x)

最後の例で、bind(g, _1, _1, _1) が生成する関数オブジェクトは入力引数を一つしか受け取らないにも関わらず、複数の引数を付けて呼び出せることに注意。 このように、余分な引数は黙って無視され、エラーにはならない。 同様に、三番目の例では最初の引数 x と二番目の引数 y は無視される。

bind に渡される引数はコピーされ、生成された関数オブジェクトの内部に保持される。 例えば、以下のコードでは、

int i = 5;

bind(f, i, _1);

i の値のコピーが関数オブジェクトに格納される。 コピーではなく参照を関数オブジェクトに格納したい場合には、boost::ref および boost::cref を使う必要がある。

int i = 5;

bind(f, ref(i), _1);

【訳注:詳しくは、refドキュメントを参照。】

Using bind with function objects

bind は通常の関数だけでなく、任意の関数オブジェクトを受け付ける。 一般的には(標準 C++ には typeof 演算子がなく、戻り型を推論できないため)、生成される関数オブジェクトの operator() の戻り型を以下のように明示的に指定する必要がある。

struct F
{
    int operator()(int a, int b) { return a - b; }
    bool operator()(long a, long b) { return a == b; }
};

F f;

int x = 104;

bind<int>(f, _1, _1)(x);		// f(x, x) つまり、ゼロ

bind<R>(, ...)シンタックスを正しく処理できないコンパイラもある。移植性のために上記を表現する代替の方法がサポートされている。

boost::bind(boost::type<int>(), f, _1, _1)(x);

しかしながら、この代替構文は回避手段としてのみ提供されていることに注意しなさい。これはインタフェースの一部ではない。

関数オブジェクトが result_type という名前の入れ子の型を開示している場合、戻り型を明示的に書く必要はない。

int x = 8;

bind(std::less<int>(), _1, 9)(x);	// x < 9

【注意:戻り型を省略する機能は、コンパイラによっては利用できない場合がある。】

Using bind with pointers to members

メンバ関数へのポインタやデータメンバへのポインタは operator() を持たないので、関数オブジェクトではない。 しかし、それでは不便なので、bind は最初の引数としてメンバへのポインタも受け付ける。 この場合、boost::mem_fn によってメンバへのポインタが関数オブジェクトに変換されて渡されたかのように振る舞う。 すなわち、式

bind(&X::f, args)

は以下のものと等価である。

bind<R>(mem_fn(&X::f), args)

ここで、RX::f の戻り型(メンバ関数の場合)、またはメンバの型への const な参照(データメンバの場合)である。

【注意:mem_fn が生成する関数オブジェクトを呼び出す際には、最初の引数としてオブジェクトのポインタ、参照またはスマートポインタを渡す。 詳しくは、mem_fnドキュメントを参照。】

例:

struct X
{
    bool f(int a);
};

X x;

shared_ptr<X> p(new X);

int i = 5;

bind(&X::f, ref(x), _1)(i);		// x.f(i)
bind(&X::f, &x, _1)(i);			//(&x)->f(i)
bind(&X::f, x, _1)(i);			// (x の内部的なコピー).f(i)
bind(&X::f, p, _1)(i);			// (p の内部的なコピー)->f(i)

最後の二つの例は「自己充足な」関数オブジェクトを生成する興味深い例である。 bind(&X::f, x, _1)x のコピーを保持する。 bind(&X::f, p, _1)p のコピーを保持し、pboost::shared_ptr であるため、関数オブジェクトは X のインスタンスへの参照を持ち、それは p のスコープを抜けたり reset() されたりしても有効である。

【訳注:つまり、bind の最初の引数がメンバ関数へのポインタである場合、次の引数はそのメンバ関数を持つクラスまたは派生クラスのオブジェクトまたはポインタ、ref()、スマートポインタでなければならない。】

Using nested binds for function composition

bind に渡される引数のうちいくつかは、それ自体が bind の入れ子になった式でもよい。

bind(f, bind(g, _1))(x);               // f(g(x))

bind によって生成された関数オブジェクトを呼び出す時には、外側の bind 式が呼ばれる前に内側の bind 式が、複数ある場合は順不同で評価される。 次に、その結果は外側の bind が評価される際の引数として渡される。 上の例で、関数オブジェクトが引数リスト (x) とともに呼び出される場合、bind(g, _1)(x) がまず評価されて g(x) となり、次に bind(f, g(x))(x) が評価され、最終的な結果は f(g(x)) となる。

bind のこの機能は、関数を合成するために使用することができる。 詳しくは、bind_as_compose.cppbind を使って Boost.Compose と同様の効果を得るサンプルがあるので、それを参照のこと。

ただし、(bind 関数の)最初の引数、つまり束縛される関数オブジェクトは、評価されないので注意すること。 特に、関数オブジェクトが bind で生成されたものや、プレースホルダ引数の場合でも評価されないので、次の例は期待通りには動かない。

typedef void (*pf)(int);

std::vector<pf> v;

std::for_each(v.begin(), v.end(), bind(_1, 5));

【訳注:動かないというか、コンパイルできない。】

期待通りの結果を得るには、ヘルパ関数オブジェクト apply を使用する必要がある。 apply はその最初の引数である関数オブジェクトを、残りの引数リストに対して適用する。 apply 関数は boost/bind/apply.hpp ヘッダファイルに定義されている。 上の例は、この apply を使って次のように書き直せばよい。

typedef void (*pf)(int);

std::vector<pf> v;

std::for_each(v.begin(), v.end(), bind(apply<void>(), _1, 5));

時には、最初の引数だけでなく、入れ子になった bind 部分式であるような他の引数を評価したくない場合もある。 この場合は、別のヘルパ関数 protect を使用するとよい。 これにより、引数の型がマスクされ、bind が認識されず、評価されない。 呼び出し時には、protect は単純に引数リストを他の関数オブジェクトのそのまま渡す。

protect 関数は boost/bind/protect.hpp ヘッダに含まれている。 bind 関数オブジェクトを評価されないように保護するには、protect(bind(f, ...)) と書けばよい。

【訳注:ここにも簡単な例が欲しい。】

Examples

Using bind with standard algorithms

class image;

class animation
{
public:

    void advance(int ms);
    bool inactive() const;
    void render(image & target) const;
};

std::vector<animation> anims;

template<class C, class P> void erase_if(C & c, P pred)
{
    c.erase(std::remove_if(c.begin(), c.end(), pred), c.end());
}

void update(int ms)
{
    std::for_each(anims.begin(), anims.end(), boost::bind(&animation::advance, _1, ms));
    erase_if(anims, boost::mem_fn(&animation::inactive));
}

void render(image & target)
{
    std::for_each(anims.begin(), anims.end(), boost::bind(&animation::render, _1, boost::ref(target)));
}

Using bind with Boost.Function

class button
{
public:

    boost::function<void> onClick;
};

class player
{
public:

    void play();
    void stop();
};

button playButton, stopButton;
player thePlayer;

void connect()
{
    playButton.onClick = boost::bind(&player::play, &thePlayer);
    stopButton.onClick = boost::bind(&player::stop, &thePlayer);
}

Limitations

bind が生成する関数オブジェクトは、引数を参照渡しで受け取る。このため、const でない一時オブジェクトやリテラル定数を受け取ることはできない。 これは、C++ 言語自体の制約であり、"the forwarding problem" として知られている。

任意の型の引数を受け取り、それらをそのまま渡すために、bind ライブラリでは、

template<class T> void f(T & t);

という形式のシグネチャを(訳注:仮引数に)使っている。 上記のように、この方法は const でない右辺値には使えない。

この問題に対して、次のようにオーバーロードを追加する「解決策」がよく提案される。

template<class T> void f(T & t);
template<class T> void f(T const & t);

残念ながら、この方法は (a) 引数が 9 つある場合、512 ものオーバーロードを提供する必要があり、(b) 引数が const である場合、シグネチャが全く同じであるために半順序(?)を定義できず、左辺値にも右辺値にもうまく働かない。

【注意:これは C++ 言語の暗い隅(?)であり、該当する問題はまだ解決されていない。】

Frequently Asked Questions

Why doesn't this compile?
(どうしてコンパイルできない?)

Troubleshooting の項を参照。

Why does this compile? It should not.
(どうしてコンパイルできちゃう? エラーになる筈なのに。)

おそらく、bind<R>(f, ...) という汎用の構文を使っているためであろう。この書き方は、bind に対して f の引数の数や戻り型に関するエラーチェックをしないように指示するものである。

What is the difference between bind(f, ...) and bind<R>(f, ...)?
(bind(f, ...) と bind<R>(f, ...) はどう違う?)

最初の形式は bindf の型を調べて、引数の数や戻り型を解決するように指示する。 引数の数の間違いは「バインド時」に検出される。 この構文はもちろん、f に対していくつかのことを要求する。 つまり、f は関数、関数ポインタ、メンバ関数へのポインタのいずれかであるか、関数オブジェクトの場合には result_type という入れ子の型を定義する必要がある。簡単に言えば、bind が認識できるものでなければならない。

二番目の形式は bindf の型を識別しないように指示する。 これは一般的には、result_type を開示しない、あるいはできない関数オブジェクトとともに用いられるが、その他に非標準の関数に対しても用いることができる。 たとえば、現在の実装は printf のような可変引数の関数を自動的に認識しないため、bind<int>(printf, ...) と書く必要がある。bind(type<R>(), f, ...) という代替シンタックスが移植性の理由からサポートされていることに注意しなさい。

【訳注:「非標準」は原文では nonstandard だが、printf が「非標準」というのは変だなぁ。】

他に考慮すべき重要な点として、コンパイラがテンプレートの部分特殊化版や関数テンプレートの半順序(?)に対応していない場合、f が関数オブジェクトであれば最初の形式は扱えず、また、f が関数(ポインタ)やメンバ関数へのポインタであれば二番目の形式は扱えないことが多い。

Does bind work with Windows API functions?
(bind は Windows の API 関数に対して使える?)

はい、#define BOOST_BIND_ENABLE_STDCALL すれば。 または、目的の関数を generic function object として扱って、bind<R>(f, ...) の構文を使っても良い。

Does bind work with COM methods?
(bind は COM のメソッドに使える?)

はい、#define BOOST_MEM_FN_ENABLE_STDCALL すれば。

Does bind work with Mac toolbox functions?
(bind は Mac の Toolbox 関数に使える?)

はい、#define BOOST_BIND_ENABLE_PASCAL すれば。 または、目的の関数を generic function object として扱って、bind<R>(f, ...) の構文を使っても良い。

Does bind work with extern "C" functions?
(bind は extern "C" な関数に使える?)

場合による。 いくつかのプラットフォームでは、extern "C" な関数へのポインタは「通常の」関数ポインタと等価であり、問題なく動く。 他のプラットフォームでは、それらは別物として扱われる。 プラットフォーム固有の bind の実装があれば、問題を透過的に解決できることが期待されるが、この実装はそうなっていない。 いつものように、回避策は目的の関数を generic function object として扱って、bind<R>(f, ...) の構文を使うことである。

【訳注:「この実装」とあるが、このドキュメントは bind の仕様を定義するもので、附属の実装は「サンプル実装」という位置付けで書かれているものと思われる。(?)

Why doesn't bind automatically recognize nonstandard functions?
(どうして bind は非標準の関数を自動的に認識しない?)

特定のベンダに縛られることを防ぐために、非標準の拡張は一般的にデフォルトで off にすべきである。 もしも固有のマクロが自動的に定義されたら、そのつもりがないのにそれらの機能を使ってしまい、知らない間に互換性を損なってしまう危険性がある。 また、いくつかのコンパイラは __stdcall (__fastcall) をデフォルトの呼び出し規約とするオプションを用意しており、特別なサポートは必要ない。

Troubleshooting

Incorrect number of arguments
(引数の数が不正)

式 bind(f, a1, a2, ..., aN) において、関数オブジェクト f はちょうど N 個の引数を取らなければならない。 このエラーは、通常「バインド時」に検出される。すなわち、bind() を呼び出している行に対してコンパイルエラーが報告される。

int f(int, int);

int main()
{
    boost::bind(f, 1);    // エラー、f は二つの引数を取る
    boost::bind(f, 1, 2); // OK
}

このエラーの変種として、メンバ関数に対する暗黙の「this」引数を忘れることも多い。

struct X
{
    int f(int);
}

int main()
{
    boost::bind(&X::f, 1);     // エラー、X::f は二つの引数を取る
    boost::bind(&X::f, _1, 1); // OK
}

【訳注:bind では、メンバ関数へのポインタは、通常の引数の前に暗黙の「this」引数をとるものとみなす。】

The function object cannot be called with the specified arguments
(関数オブジェクトは指定された引数とともに呼び出すことはできない)

通常の関数呼び出しと同様、束縛される関数オブジェクトは引数リストと互換性を持つ必要がある。 非互換性は、通常コンパイラによって「呼び出し時」に検出され、bind.hpp の次のような行に対するエラーとなる。

    return f(a[a1_], a[a2_]);

An example of this kind of error:

int f(int);

int main()
{
    boost::bind(f, "incompatible");      // OK、呼び出さないので
    boost::bind(f, "incompatible")();    // エラー、"incompatible" は int ではない
    boost::bind(f, _1);                  // OK
    boost::bind(f, _1)("incompatible");  // エラー、"incompatible" は int ではない
}

Accessing an argument that does not exist
(存在しない引数へのアクセス)

プレースホルダ _N は引数リストの N 番目の引数を、「呼び出し時」に選択する。 当然、引数リストの範囲外のものにアクセスしようとすればエラーになる。

int f(int);

int main()
{
    boost::bind(f, _1);                  // OK
    boost::bind(f, _1)();                // エラー、一番目の引数は存在しない
}

このエラーは、通常 bind.hpp の次のような行に対して報告される。

    return f(a[a1_]);

std::bind1st(f, a) の代わりに使う場合、bind(f, a, _1) ではなく間違って bind(f, a, _2) としてしまうことも多い。

Inappropriate use of bind(f, ...)
(bind(f, ...) の不適切な使用)

bind(f, a1, a2, ..., aN) の形式f を自動的に認識させる。 これは、任意の関数オブジェクトに対して働くわけではない。f は関数またはメンバ関数へのポインタでなければならない。

この形式を result_type を定義する関数オブジェクトに使えるのは、部分特殊化版や半順序(?)サポートしているコンパイラに限られる。 特に、MSVC のバージョン 7.0 までは、関数オブジェクトに対するこの構文はサポートしない。

【訳注:原文では MSVC up to version 7.0 となっているが、これは 7.0 を含むのだろうか?】

Inappropriate use of bind<R>(f, ...)
(bind<R>(f, ...) の不適切な使用)

bind<R>(f, a1, a2, ..., aN) の形式は任意の関数オブジェクトをサポートする。

この形式を関数やメンバ関数ポインタに使うことは(推奨されないが)半順序をサポートするコンパイラでのみ可能である。特に、MSVC のバージョン 7.0 までは、関数とメンバ関数ポインタに対して、完全にこの構文をサポートしなお。

Binding a nonstandard function
(非標準の関数の束縛)

デフォルトでは、bind(f, a1, a2, ..., aN) の形式 は「普通の」 C++ 関数と関数ポインタを認識する。異なる呼び出し規則を用いる関数や、std::printfのような可変個引数をとる関数ではうまくいかない。一般的な bind<R>(f, a1, a2, ..., aN) の形式 が非標準な関数に対してうまくいく。

std::strcmp のような extern "C" 宣言された関数は bind の短い形式では認識されないプラットホームもある。

"__stdcall" and "pascal" Support を参照せよ。

【訳注:ここの A タグに name があったためリンクがおかしくなっていたので修正した。本家にも問い合わせるべき。】

const in signatures
(シグネチャが const を含む)

MSVC 6.0 や Borland C++ 5.5.1 を含むいくつかのコンパイラは関数のシグネチャ中の最上位の const の扱いに問題がある:

【訳注:top-level cv-qualifers って典型的な訳は何なんでしょ。】

int f(int const);

int main()
{
    boost::bind(f, 1);     // error
}

回避手段: const 限定子を引数から取り除きなさい。

MSVC specific: using boost::bind;
(MSVC 特有の問題: using boost::bind)

(7.0 までの) MSVC では、boost::bind が using 宣言によってスコープに組み込まれた時:

using boost::bind;

bind<R>(...) 構文はうまく働かない。回避手段: boost::bind と、限定された名前を使うか、using 指令を代わりに使いなさい:

using namespace boost;

MSVC specific: class templates shadow function templates
(MSVC特有の問題: クラステンプレートが関数テンプレートを隠す)

(7.0 までの) MSVC では、ネストした bind という名前のクラステンプレートは関数テンプレートの boost::bind を隠してしまい、bind<R>(...) の構文を駄目にしてしまうだろう。不幸なことにいくつかのライブラリは bind という名前のネストしたクラステンプレートを含んでいる。(皮肉なことに、そういったコードはしばしば MSVC に特有な回避手段であったりする)

回避手段は他の bind(type<R>(), f, ...) 構文を使うことだ。

MSVC specific: ... in signatures treated as type
(MSVC 特有の問題: シグネチャの中の ... が方として扱われる)

(7.0 までの) MSVC は (std::printf のような) 可変個引数を持つ関数の中の省略記号を型として扱う。それゆえ、それは (現在の実装では不正な) 以下の形式を許可する:

    bind(printf, "%s\n", _1);

そして、正しいバージョンを拒絶する:

    bind<int>(printf, "%s\n", _1);

Interface

Synopsis

namespace boost
{

// no arguments

template<class R, class F> unspecified-1 bind(F f);

template<class F> unspecified-1-1 bind(F f);

template<class R> unspecified-2 bind(R (*f) ());

// one argument

template<class R, class F, class A1> unspecified-3 bind(F f, A1 a1);

template<class F, class A1> unspecified-3-1 bind(F f, A1 a1);

template<class R, class B1, class A1> unspecified-4 bind(R (*f) (B1), A1 a1);

template<class R, class T, class A1> unspecified-5 bind(R (T::*f) (), A1 a1);

template<class R, class T, class A1> unspecified-6 bind(R (T::*f) () const, A1 a1);

template<class R, class T, class A1> unspecified-6-1 bind(R T::*f, A1 a1);

// two arguments

template<class R, class F, class A1, class A2> unspecified-7 bind(F f, A1 a1, A2 a2);

template<class F, class A1, class A2> unspecified-7-1 bind(F f, A1 a1, A2 a2);

template<class R, class B1, class B2, class A1, class A2> unspecified-8 bind(R (*f) (B1, B2), A1 a1, A2 a2);

template<class R, class T, class B1, class A1, class A2> unspecified-9 bind(R (T::*f) (B1), A1 a1, A2 a2);

template<class R, class T, class B1, class A1, class A2> unspecified-10 bind(R (T::*f) (B1) const, A1 a1, A2 a2);

// implementation defined number of additional overloads for more arguments

}

namespace
{

unspecified-placeholder-type-1 _1;

unspecified-placeholder-type-2 _2;

unspecified-placeholder-type-3 _3;

// implementation defined number of additional placeholder definitions

}

Common requirements

All unspecified-N types returned by bind are CopyConstructible. unspecified-N::result_type is defined as the return type of unspecified-N::operator().

All unspecified-placeholder-N types are CopyConstructible. Their copy constructors do not throw exceptions.

Common definitions

The function µ(x, v1, v2, ..., vm), where m is a nonnegative integer, is defined as:

bind

template<class R, class F> unspecified-1 bind(F f)

Returns: A function object λ such that the expression λ(v1, v2, ..., vm) is equivalent to f(), implicitly converted to R.

Throws: Nothing unless the copy constructor of F throws an exception.

template<class F> unspecified-1-1 bind(F f)

Effects: Equivalent to bind<typename F::result_type, F>(f);

Notes: Implementations are allowed to infer the return type of f via other means as an extension, without relying on the result_type member.

template<class R> unspecified-2 bind(R (*f) ())

Returns: A function object λ such that the expression λ(v1, v2, ..., vm) is equivalent to f().

Throws: Nothing.

template<class R, class F, class A1> unspecified-3 bind(F f, A1 a1)

Returns: A function object λ such that the expression λ(v1, v2, ..., vm) is equivalent to f(µ(a1, v1, v2, ..., vm)), implicitly converted to R.

Throws: Nothing unless the copy constructors of F or A1 throw an exception.

template<class F, class A1> unspecified-3-1 bind(F f, A1 a1)

Effects: Equivalent to bind<typename F::result_type, F, A1>(f, a1);

Notes: Implementations are allowed to infer the return type of f via other means as an extension, without relying on the result_type member.

template<class R, class B1, class A1> unspecified-4 bind(R (*f) (B1), A1 a1)

Returns: A function object λ such that the expression λ(v1, v2, ..., vm) is equivalent to f(µ(a1, v1, v2, ..., vm)).

Throws: Nothing unless the copy constructor of A1 throws an exception.

template<class R, class T, class A1> unspecified-5 bind(R (T::*f) (), A1 a1)

Effects: Equivalent to bind<R>(boost::mem_fn(f), a1);

template<class R, class T, class A1> unspecified-6 bind(R (T::*f) () const, A1 a1)

Effects: Equivalent to bind<R>(boost::mem_fn(f), a1);

template<class R, class T, class A1> unspecified-6-1 bind(R T::*f, A1 a1)

Effects: Equivalent to bind<R const &>(boost::mem_fn(f), a1);

template<class R, class F, class A1, class A2> unspecified-7 bind(F f, A1 a1, A2 a2)

Returns: A function object λ such that the expression λ(v1, v2, ..., vm) is equivalent to f(µ(a1, v1, v2, ..., vm), µ(a2, v1, v2, ..., vm)), implicitly converted to R.

Throws: Nothing unless the copy constructors of F, A1 or A2 throw an exception.

template<class F, class A1, class A2> unspecified-7-1 bind(F f, A1 a1, A2 a2)

Effects: Equivalent to bind<typename F::result_type, F, A1, A2>(f, a1, a2);

Notes: Implementations are allowed to infer the return type of f via other means as an extension, without relying on the result_type member.

template<class R, class B1, class B2, class A1, class A2> unspecified-8 bind(R (*f) (B1, B2), A1 a1, A2 a2)

Returns: A function object λ such that the expression λ(v1, v2, ..., vm) is equivalent to f(µ(a1, v1, v2, ..., vm), µ(a2, v1, v2, ..., vm)).

Throws: Nothing unless the copy constructors of A1 or A2 throw an exception.

template<class R, class T, class B1, class A1, class A2> unspecified-9 bind(R (T::*f) (B1), A1 a1, A2 a2)

Effects: Equivalent to bind<R>(boost::mem_fn(f), a1, a2);

template<class R, class T, class B1, class A1, class A2> unspecified-10 bind(R (T::*f) (B1) const, A1 a1, A2 a2)

Effects: Equivalent to bind<R>(boost::mem_fn(f), a1, a2);

Additional overloads

Implementations are allowed to provide additional bind overloads in order to support more arguments or different function pointer variations.

Implementation

Files

Dependencies

Number of Arguments

This implementation supports function objects with up to nine arguments. This is an implementation detail, not an inherent limitation of the design.

"__stdcall", "__fastcall", and "pascal" Support

Some platforms allow several types of (member) functions that differ by their calling convention (the rules by which the function is invoked: how are arguments passed, how is the return value handled, and who cleans up the stack - if any.)

For example, Windows API functions and COM interface member functions use a calling convention known as __stdcall.Borland VCL components use __fastcall. Mac toolbox functions use a pascal calling convention.

To use bind with __stdcall functions, #define the macro BOOST_BIND_ENABLE_STDCALL before including <boost/bind.hpp>.

To use bind with __stdcall member functions, #define the macro BOOST_MEM_FN_ENABLE_STDCALL before including <boost/bind.hpp>.

To use bind with __fastcall functions, #define the macro BOOST_BIND_ENABLE_FASTCALL before including <boost/bind.hpp>.

To use bind with __fastcall member functions, #define the macro BOOST_MEM_FN_ENABLE_FASTCALL before including <boost/bind.hpp>.

To use bind with pascal functions, #define the macro BOOST_BIND_ENABLE_PASCAL before including <boost/bind.hpp>.

[Note: this is a non-portable extension. It is not part of the interface.]

[Note: Some compilers provide only minimal support for the __stdcall keyword.]

Using the BOOST_BIND macro

A bug in MSVC (up to version 7.0) causes boost::bind to be incompatible with libraries that contain nested class templates named bind. To work around this problem, #define the macro BOOST_BIND to something other than bind (before the inclusion of <boost/bind.hpp>) and use this identifier throughout your code wherever you'd normally use bind.

[Note: BOOST_BIND is not a general renaming mechanism. It is not part of the interface, and is not guaranteed to work on other compilers, or persist between library versions. In short, don't use it unless you absolutely have to.]

visit_each support

Function objects returned by bind support the experimental and undocumented, as of yet, visit_each enumeration interface.

See bind_visitor.cpp for an example.

Acknowledgements

Earlier efforts that have influenced the library design:

Doug Gregor suggested that a visitor mechanism would allow bind to interoperate with a signal/slot library.

John Maddock fixed a MSVC-specific conflict between bind and the type traits library.

Numerous improvements were suggested during the formal review period by Ross Smith, Richard Crossley, Jens Maurer, Ed Brey, and others. Review manager was Darin Adler.

The precise semantics of bind were refined in discussions with Jaakko Järvi.

Dave Abrahams fixed a MSVC-specific conflict between bind and the iterator adaptors library.

Dave Abrahams modified bind and mem_fn to support void returns on deficient compilers.

Mac Murrett contributed the "pascal" support enabled by BOOST_BIND_ENABLE_PASCAL.




Copyright © 2001, 2002 by Peter Dimov and Multi Media Ltd. Permission to copy, use, modify, sell and distribute this document is granted provided this copyright notice appears in all copies. This document is provided "as is" without express or implied warranty, and with no claim as to its suitability for any purpose.