std.bind
関数に引数を束縛します。 このモジュールは非推奨です。delegate を使用して下さい。References:
boost::bind Source:
std/bind.d
License:
Boost License 1.0 Authors:
Tomasz Stachowiak
- deprecated const DynArg!(0) _0;
deprecated const DynArg!(1) _1;
deprecated const DynArg!(2) _2;
deprecated const DynArg!(3) _3;
deprecated const DynArg!(4) _4;
deprecated const DynArg!(5) _5;
deprecated const DynArg!(6) _6;
deprecated const DynArg!(7) _7;
deprecated const DynArg!(8) _8;
deprecated const DynArg!(9) _9; - 'bind' 関数に渡されたときに、あとで動的に引数が入る場所を表すマーカーです。
Boostでは_1, _2, _3, ... と名前がついていますが、このライブラリでは _0, _1, _2, ... です。
- 基本的な操作を備えたタプル構造体です。
- 最後に型Xを追加したタプル型を取得します
- 最後にX型の要素を追加したタプルを取得します
- 最後にX型の要素を追加したタプルを取得します
- 先頭に型Xを追加したタプル型を取得します
- 先頭にX型の要素を追加したタプルを取得します
- 先頭にX型の要素を追加したタプルを取得します
- 現在のタプルの後ろに別のタプル型を追加します
- 空タプル構造体です
- 空の組み込みのタプル
- 空の組み込みのタプル
- 指定された引数から動的にタプルを作成
- 指定された型がTuple構造体かどうかを判定する
- 指定した関数の呼び出しに必要な最小の引数の個数を返します
- 束縛済みの関数用のコンテキストです
- bind() は、関数の引数を "束縛" できます。返値として、
引数の順番が違ったり個数が少ない関数を作り出して返します。関数の合成もbindで行うことができます。
bind() の使い方の構文は以下の通りです:
bind(関数かdelegateへのポインタ { , 引数 });
引数 は以下のいずれかです:- 静的/束縛 引数 (即値)
- 別の束縛済み関数オブジェクト
- 動的引数 [0-9]、たとえば _0 や _3 や _9
結果は関数オブジェクトで、call(), func(), opCall() のいずれかで呼び出せます。 さらに便利な ptr() 関数も用意されていて、これはcall/func/opCallのdelegateを返します。
結果のdelegateは、動的引数が使われた個数とぴったり一致する数の引数を受け取ります。- bind(&foo, _0, _1) // 2引数をとるdelegateになる - bind(&foo, _1, _0) // 2引数をとるdelegateになる - bind(&bar, _0, _1, _2, _0) // 3引数をとるdelegateになる
動的引数の型は束縛される関数の型から取得され、必要なら型の調整が行われます。 例えば、次のようなbindを行うと:void foo(int a, long b) // with: bind(&foo, _0, _0)
最適な型の引数を1つとるdelegateになります。最適な型は std.typetuple.DerivedToFront を使って計算されますので、int と long なら long が選ばれます。一般に、bind は他の動的引数全てに暗黙変換できるような型を探そうとします。
Note:
数値型の場合、明示的な、しかし(ユーザーには)透過的なキャストが行われます。
関数合成も直感的に記述できます:bind(&f1, bind(&f2, _0))
これは引数を1つとって、それにf2を適用してから結果を引数にf1を呼び出すdelegateとなります。 数学的に言うと、これは関数合成です:f1(f2(_0))
ある関数が複数回束縛されたならば、それは複数回呼び出されます。bind は遅延評価は行いません。なのでbind(&f3, bind(&f4, _0), bind(&f4, _0))
は呼ばれるたびにf4を二回呼び出して、f3への引数を用意し、次にf3を呼び出すdelegateになります
bind() のサポートするもう一つの機能は、タプルの自動展開です。つまり、次のような関数:void foo(int a, int b) Tuple!(int, int) bar()
をこうやってbindして書くことが可能になります。bind(&foo, bind(&bar)) // or bind(&foo, tuple(23, 45))
- bindAlias() は bind() とよく似ていますが、もっと強力です。可能なら、bind() よりも bindAlias
構文は:
bindAlias!(Function)(argument, argument, argument, argument, ...);
bindAlias には、直接aliasを指定できるという利点があります。これによって、元々の関数のデフォルト引数を再利用することができ、ユーザーがその部分をわざわざ束縛する必要がなくなります。 これは、作ったdelegateが引数を省略してもしなくても呼び出せるようになっている、という意味ではありません。 に指定された関数がデフォルト引数を持つ場合、その引数に関しては、何も指定せずとも自動で束縛される、という意味です。
さらに、bindAlias は out/ref 引数もうまく処理します。これは内部で扱いをポインタに変換することで実現されています。次のような関数は:void foo(ref a)
こうやって束縛します:int x; bindAlias!(foo)(&x);
注意: 束縛時点で参照がnullなことをチェックする機能はありませんが、呼び出し時にはnullチェックが行われます。 これは、リリースモードでコンパイルするか version=BindNoNullCheck でコンパイルするとOFFにできます。