原文:http://www.boost.org/libs/bind/bind.html
![]() |
bind.hpp |
boost::bind は標準ライブラリの関数 std::bind1st および std::bind2nd を汎用化したものである。 関数オブジェクトだけでなく、関数や関数へのポインタ、メンバ関数へのポインタをサポートし、任意の引数を特定の値に束縛したり、入力引数を、もとの順番に関係なく自由な位置に移し替えることができる。 bind が扱うことのできる関数オブジェクトには、特別な条件はない。 特に、標準関数が要求する typedef result_type や first_argument_type および second_argument_type は必須ではない。
【訳注:このような関数を一般に「バインダ」または「束縛子」と呼ぶ。なお、lambda ライブラリも同様の機能を持っている。】
【訳注:「入力引数」とは、bind によって生成された関数オブジェクトを呼び出す時に渡される引数。例えば、bind(f, _1, 5)(x) における x のこと。】
以下の関数が定義されているとき、
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 を参照。】
比較のため、同じ操作を標準ライブラリのプリミティブを使って書くとこうなる。
std::bind2nd(std::ptr_fun(f), 5)(x);
bind は std::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 は無視される。
【訳注:エラーにならずに無視される理由は、lambda のドキュメントの Appendix を参照。】
bind に渡される引数はコピーされ、生成された関数オブジェクトの内部に保持される。 例えば、以下のコードでは、
int i = 5; bind(f, i, _1);
i の値のコピーが関数オブジェクトに格納される。 コピーではなく参照を関数オブジェクトに格納したい場合には、boost::ref および boost::cref を使う必要がある。
int i = 5; bind(f, ref(i), _1);
【訳注:詳しくは、ref のドキュメントを参照。】
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) つまり、ゼロ
関数オブジェクトが result_type という名前の入れ子の型を開示している場合、戻り型を明示的に書く必要はない。
int x = 8; bind(std::less<int>(), _1, 9)(x); // x < 9
【注意:戻り型を省略する機能は、コンパイラによっては利用できない場合がある。】
メンバ関数へのポインタやデータメンバへのポインタは operator() を持たないので、関数オブジェクトではない。 しかし、それでは不便なので、bind は最初の引数としてメンバへのポインタも受け付ける。 この場合、boost::mem_fn によってメンバへのポインタが関数オブジェクトに変換されて渡されたかのように振る舞う。 すなわち、式
bind(&X::f, args)
は以下のものと等価である。
bind<R>(mem_fn(&X::f), args)
ここで、R は X::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 のコピーを保持し、p が boost::shared_ptr であるため、関数オブジェクトは X のインスタンスへの参照を持ち、それは p のスコープを抜けたり reset() されたりしても有効である。
【訳注:つまり、bind の最初の引数がメンバ関数へのポインタである場合、次の引数はそのメンバ関数を持つクラスまたは派生クラスのオブジェクトまたはポインタ、ref()、スマートポインタでなければならない。】
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.cpp に bind を使って 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, ...)) と書けばよい。
【訳注:ここにも簡単な例が欲しい。】
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))); }
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); }
bind が生成する関数オブジェクトは、引数を参照渡しで受け取る。このため、const でない一時オブジェクトやリテラル定数を受け取ることはできない。 これは、C++ 言語自体の制約であり、「転送関数問題」として知られている。
任意の型の引数を受け取り、それらをそのまま渡すために、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++ 言語の暗い隅(dark corner)であり、該当する問題はまだ解決されていない。】
おそらく、bind<R>(f, ...) という汎用の構文を使っているためであろう。この書き方は、bind に対して f の引数の数や戻り型に関するエラーチェックをしないように指示するものである。
最初の形式は bind に f の型を調べて、引数の数や戻り型を解決するように指示する。 引数の数の間違いは「バインド時」に検出される。 この構文はもちろん、f に対していくつかのことを要求する。 つまり、f は関数、関数ポインタ、メンバ関数へのポインタのいずれかであるか、関数オブジェクトの場合には result_type という入れ子の型を定義する必要がある。簡単に言えば、bind が認識できるものでなければならない。
二番目の形式は bind に f の型を識別しないように指示する。 これは一般的には、result_type を開示しない、あるいはできない関数オブジェクトとともに用いられるが、その他に非標準の関数に対しても用いることができる。 たとえば、現在の実装は printf のような可変引数の関数を自動的に認識しないため、bind<int>(printf, ...) と書く必要がある。
【訳注:「非標準」は原文では nonstandard だが、printf が「非標準」というのは変だなぁ。】
他に考慮すべき重要な点として、コンパイラがテンプレートの部分特殊化版や関数テンプレートの半順序(?)に対応していない場合、f が関数オブジェクトであれば最初の形式は扱えず、また、f が関数(ポインタ)やメンバ関数へのポインタであれば二番目の形式は扱えないことが多い。
はい、#define BOOST_BIND_ENABLE_STDCALL すれば。 または、目的の関数を generic function object として扱って、bind<R>(f, ...) の構文を使っても良い。
はい、#define BOOST_MEM_FN_ENABLE_STDCALL すれば。
はい、#define BOOST_BIND_ENABLE_PASCAL すれば。 または、目的の関数を generic function object として扱って、bind<R>(f, ...) の構文を使っても良い。
場合による。 いくつかのプラットフォームでは、extern "C" な関数へのポインタは「通常の」関数ポインタと等価であり、問題なく動く。 他のプラットフォームでは、それらは別物として扱われる。 プラットフォーム固有の bind の実装があれば、問題を透過的に解決できることが期待されるが、この実装はそうなっていない。 いつものように、回避策は目的の関数を generic function object として扱って、bind<R>(f, ...) の構文を使うことである。
【訳注:「この実装」とあるが、このドキュメントは bind の仕様を定義するもので、附属の実装は「サンプル実装」という位置付けで書かれているものと思われる。(?)】
特定のベンダに縛られることを防ぐために、非標準の拡張は一般的にデフォルトで off にすべきである。 もしも固有のマクロが自動的に定義されたら、そのつもりがないのにそれらの機能を使ってしまい、知らない間に互換性を損なってしまう危険性がある。 また、いくつかのコンパイラは __stdcall (__fastcall) をデフォルトの呼び出し規約とするオプションを用意しており、特別なサポートは必要ない。
式 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」引数をとるものとみなす。】
通常の関数呼び出しと同様、束縛される関数オブジェクトは引数リストと互換性を持つ必要がある。 非互換性は、通常コンパイラによって「呼び出し時」に検出され、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 ではない }
プレースホルダ _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) としてしまうことも多い。
bind(f, a1, a2, ..., aN) 形式は f を自動的に認識させる。 これは、任意の関数オブジェクトに対して働くわけではない。f は関数またはメンバ関数へのポインタでなければならない。
この形式を result_type を定義する関数オブジェクトに使えるのは、部分特殊化版や半順序(?)をサポートしているコンパイラに限られる。 特に、MSVC のバージョン 7.0 までは、関数オブジェクトに対するこの構文はサポートしない。
【訳注:原文では MSVC up to version 7.0 となっているが、これは 7.0 を含むのだろうか?】
bind<R>(f, a1, a2, ..., aN) 形式は任意の関数オブジェクトをサポートする。
この形式を関数やメンバ関数のポインタに対して使用することが可能(推奨はしないが)なのは、半順序(?)をサポートしているコンパイラに限られる。 特に、MSVC のバージョン 7.0 までは、関数やメンバ関数のポインタに対するこの構文はサポートしない。
デフォルトでは、bind(f, a1, a2, ..., aN) 形式は「通常の」C++ 関数と関数ポインタを認識する。 異なる呼び出し規約を使用する関数や、std::printf のように可変引数を取る関数はうまくいかない。(?) 汎用の bind<R>(f, a1, a2, ..., aN) 形式は非標準の関数に対してうまくいく。(?)
いくつかのプラットフォームでは、std::strcmp などの extern "C" な関数は bind の短い形式で認識される。
詳しくは "__stdcall" and "pascal" Support を参照。
MSVC 6.0 や Borland C++ 5.5.1 など、いくつかのコンパイラでは、関数シグネチャのトップレベルに const があるとうまくいかない。
int f(int const); int main() { boost::bind(f, 1); // error }
回避策:const 修飾子を仮引数から取り除く。
【訳注:トップレベルの const のみ取り除くこと。たとえば、T * const の const は取り除くが、const T * や const T & の const は取り除いてはいけない。】
MSVC(バージョン 7.0 まで)で、boost::bind が using 宣言によってスコープに導入された場合、
using boost::bind;
bind<R>(...) の構文は使えない。 回避策:名前空間名付きの名前 boost::bind を使うか、次のような using ディレクティブ(?)を使用する。
using namespace boost;
MSVC(バージョン 7.0 まで)で、(訳注:boost 以外の名前空間に)入れ子になった bind という名前のクラステンプレートが存在する場合、関数テンプレート boost::bind を隠してしまい、bind<R>(...) の構文がエラーになる。 残念ながら、いくつかのライブラリに bind という名前のクラステンプレートが含まれている(皮肉なことに、そのようなコードはしばしば MSVC 固有のバグ回避策だったりする)。 そのようなライブラリを見つけたら、パッチを当てるか、作者またはメンテナに連絡するのが良いだろう。 その他のオプションとしては、BOOST_BIND マクロを利用して bind の名前を変更する方法がある。
MSVC(バージョン 7.0 まで)は可変引数を持つ関数(boost::bind など)の ellipsis(?)を型として取り扱う。 このため、現在の実装では正しくない形式を受け付け、
bind(printf, "%s\n", _1);
正しいバージョンを拒否する。
bind<int>(printf, "%s\n", _1);
namespace boost { // 無引数 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) ()); // 一引数 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); // 二引数 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); // 実装定義の個数の引数に対する追加のオーバーロード } namespace { unspecified-placeholder-type-1 _1; unspecified-placeholder-type-2 _2; unspecified-placeholder-type-3 _3; // 実装定義の個数の追加のプレースホルダの定義 }
bind が返す全ての unspecified-N 型は CopyConstructible 要求を満たす。 unspecified-N::result_type は unspecified-N::operator() の戻り型として定義される。
全ての unspecified-placeholder-N 型は CopyConstructible 要求を満たす。 それらのコピーコンストラクタは、例外を投げない。
【訳注:ここに CopyConstructible 要求について書く。】
m を非負の整数として、関数 μ(x, v1, v2, ..., vm) を以下のように定義する。
Returns: 関数オブジェクト λ、ただし、式 λ(v1, v2, ..., vm) が f() と等価で、R への暗黙の変換が存在する。
Throws: F のコピーコンストラクタが投げるもの以外、なし。
Effects: bind<typename F::result_type, F>(f); と等価。
Notes: 実装は、拡張として f の戻り型を result_type メンバによらずに、他の方法で推論しても良い。
Returns: 関数オブジェクト λ、ただし、式 λ(v1, v2, ..., vm) は f() と等価。
Throws: なし。
Returns: 関数オブジェクト λ、ただし、式 λ(v1, v2, ..., vm) は f(μ(a1, v1, v2, ..., vm)) と等価で、R への暗黙の変換が存在する。
Throws: F または A1 のコピーコンストラクタが投げるもの以外、なし。
Effects: bind<typename F::result_type, F, A1>(f, a1); と等価。
Notes: 実装は、拡張として f の戻り型を result_type メンバによらずに、他の方法で推論しても良い。
Returns: 関数オブジェクト λ、ただし、式 λ(v1, v2, ..., vm) は f(μ(a1, v1, v2, ..., vm)) と等価。
Throws: Nothing unless the copy constructor of A1 throws an exception.
Effects: bind<R>(boost::mem_fn(f), a1); と等価。
Effects: bind<R>(boost::mem_fn(f), a1); と等価。
Effects: bind<R const &>(boost::mem_fn(f), a1); と等価。
Returns: 関数オブジェクト λ、ただし、式 λ(v1, v2, ..., vm) は f(μ(a1, v1, v2, ..., vm), μ(a2, v1, v2, ..., vm)) と等価で、R への暗黙の変換が存在する。
Throws: F, A1 または A2 のコピーコンストラクタが投げるもの以外、なし。
Effects: bind<typename F::result_type, F, A1, A2>(f, a1, a2); と等価。
Notes: 実装は、拡張として f の戻り型を result_type メンバによらずに、他の方法で推論しても良い。
Returns: 関数オブジェクト λ、ただし、式 λ(v1, v2, ..., vm) は f(μ(a1, v1, v2, ..., vm), μ(a2, v1, v2, ..., vm)) と等価。
Throws: A1 または A2 のコピーコンストラクタが投げるもの以外、なし。
Effects: bind<R>(boost::mem_fn(f), a1, a2); と等価。
Effects: bind<R>(boost::mem_fn(f), a1, a2); と等価。
実装は、より多くの引数や、異なる関数ポインタの変種をサポートするために、bind の追加のオーバーロードを提供しても良い。
この実装は、最大9つまでの引数を持つ関数オブジェクトをサポートする。 これは実装詳細であり、設計からくる制限ではない。
いくつかのプラットフォームは、呼び出し規約(関数を呼び出す際の規約:引数の渡し方、戻り値の扱い方、誰がスタックを元に戻すか、など)が異なる複数の型の(メンバ)関数を許す。
例えば、Windows の API 関数や COM インターフェイスのメンバ関数は __stdcall として知られる呼び出し規約を使用し、Borland の VCL コンポーネントは __fastcall を使用する。 また、Mac のツールボックス関数は、pascal 呼び出し規約を使用する。(訳注:Classic Mac OS の場合。)
bind を __stdcall 関数に対して使用する場合、<boost/bind.hpp> をインクルードする前に BOOST_BIND_ENABLE_STDCALL マクロを #define すること。
bind を __stdcall メンバ関数に対して使用する場合、<boost/bind.hpp> をインクルードする前に BOOST_MEM_FN_ENABLE_STDCALL マクロを #define すること。
bind を __fastcall 関数に対して使用する場合、<boost/bind.hpp> をインクルードする前に BOOST_BIND_ENABLE_FASTCALL マクロを #define すること。
bind を __fastcall メンバ関数に対して使用する場合、<boost/bind.hpp> をインクルードする前に BOOST_MEM_FN_ENABLE_FASTCALL マクロを #define すること。
bind を pascal 関数に対して使用する場合、<boost/bind.hpp> をインクルードする前に BOOST_BIND_ENABLE_PASCAL マクロを #define すること。
【注意:これはポータブルでない拡張であり、インターフェイスの一部ではない。】
【注意:いくつかのコンパイラは __stdcall キーワードに対する最低限のサポートしか提供しない。】
MSVC(バージョン 7.0 まで)のバグ により、boost::bind は bind という名前の入れ子のクラステンプレートを含むライブラリとは互換性がない。 この問題を回避するためには、(<boost/bind.hpp> をインクルードする前に)BOOST_BIND マクロを bind 以外のものに #define して、プログラム中で通常 bind を使用する全ての場所で代わりにその識別子を使用する必要がある。
【注意:BOOST_BIND は汎用の名前の付け替え機構ではない。インターフェイスの一部ではなく、他のコンパイラでうまく働いたり、ライブラリのバージョン間で互換性がある保証もない。つまり、どうしても使わざるを得ない場合以外は使わないこと。】
bind が返す関数オブジェクトは、今のところドキュメント化されていない実験的な機能である visit_each 列挙インターフェイスをサポートする。
詳しくは、bind_visitor.cpp の例を参照。
ライブラリの設計に際しては、先行する以下のものを参考にした。
Doug Gregor は bind を signal/slot ライブラリと協調して動作できるようにする visitor 機構を提案した。
John Maddock は MSVC に固有な bind と type traits library の衝突を修正した。
Darin Adler が管理する最終レビューにおいて、Ross Smith, Richard Crossley, Jens Maurer, Ed Brey, その他により、いくつもの改善項目が提案された。
Jaakko Järvi との議論において、bind の精密なセマンティクスが定義された。
Dave Abrahams は MSVC に固有な bind と iterator adaptors library の衝突を修正した。
Dave Abrahams は bind と mem_fn を修正して、不完全なコンパイラでも void の戻り型をサポートするようにした。
Mac Murrett は BOOST_BIND_ENABLE_PASCAL マクロによる "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.
Japanese Translation Copyright © 2003 by Hoshi Takanori
オリジナルの、及びこの著作権表示が全ての複製の中に現れる限り、この文書の複製、利用、変更、販売そして配布を認める。このドキュメントは「あるがまま」に提供されており、いかなる明示的、暗黙的保証も行わない。また、いかなる目的に対しても、その利用に適していると主張しない。