Hatena::ブログ(Diary)

joynote break;

2010-07-23

[][] std::bindをやっと理解

bindが今までイマイチ理解できてなかったけど、書いてみたら一発で理解。

要は、function(関数ポインタ/関数オブジェクト/ラムダ式)の引数を束縛して新しいfunctionオブジェクトを生成してるのね。

#include <functional>
#include <iostream>

using namespace std;

void Func(int a, int b)
{
	cout << a*b << endl;
}

int main(){
	// intの引数1つのfunction
	function<void (int)> func;
	// int引数2つのfunctionの片方を定数(3)で束縛して、int引数1つのfunctionに入れる
	func = bind(Func,placeholders::_1,3);
	// 動く
	func(4);
	return 0;
}

出力結果:

12


placeholders::_n(1...)について。

placeholdersは"bindによって新しく作られる関数オブジェクトの第n引数に入れられた値"を、作成元のオブジェクトのplaceholdersが書かれた場所に入れる(のと同じ事になる処理をするような)指定をする。

つまり、

#include <functional>
#include <iostream>
 
using namespace std;
 
void Func(int a, int b, int c)
{
        cout << a*b+c << endl;
}
 
int main(){
        // intの引数2つのfunction
        function<void (int,int)> funcA;
        function<void (int,int)> funcB;
        function<void (int,int)> funcC;
 
        // 元:第1引数 => 新:第1引数
        // 元:第2引数 => 新:第2引数
        // 元:第3引数 => 新:3(定数)
        funcA = bind(Func,placeholders::_1,placeholders::_2,3);
 
        // 元:第1引数 => 新:第1引数
        // 元:第2引数 => 新:3(定数)
        // 元:第3引数 => 新:第2引数
        funcB = bind(Func,placeholders::_1,3,placeholders::_2);

        // 元:第1引数 => 新:第2引数
        // 元:第2引数 => 新:3(定数)
        // 元:第3引数 => 新:第1引数 みたいな入れ替えも可能
        funcC = bind(Func,placeholders::_2,3,placeholders::_1);
 
        // 動く
        funcA(4,5); // 4*5+3 = 23
        funcB(4,5); // 4*3+5 = 17
        funcC(4,5); // 5*3+4 = 19
        return 0;
}

出力結果:

23
17
19


となる。