std::bind
提供: C++入門
スポンサーリンク
std::bind とは、functionの引数を束縛し、新しいオブジェクトを生成します。
読み方
- std::bind
- えすてぃーでぃー ばいんど
目次
概要
std::bindは、関数の引数を束縛したオブジェクトを作成できます。 bind時に引数を束縛しない場合には、std::placeholdersを指定します。
ヘッダファイル
#include <functional>
簡単なstd::bind1の例
これは、参照なしの例です。
ソースコード std_bind1.cpp
_1や_2は、std::placeholdersに定義されています。
#include <iostream> #include <functional> void f1() { std::cout << __PRETTY_FUNCTION__ << std::endl; } void f2(int x) { std::cout << __PRETTY_FUNCTION__ << " " << x << std::endl; } void f3(int x, int y) { std::cout << __PRETTY_FUNCTION__ << " " << x << " " << y << std::endl; } int main(int argc, char const* argv[]) { using namespace std::placeholders; auto func1 = std::bind(f1); // 引数なし func1(); // 呼び出し auto func2 = std::bind(f2,_1); // 引数が1つ func2(123); // 呼び出し auto func3 = std::bind(f3,_1,_2); // 引数が2つ func3(467, 789); // 呼び出し return 0; }
コンパイル
g++49 -std=c++11 -I/usr/local/lib/gcc49/include/c++/ \ -Wl,-rpath=/usr/local/lib/gcc49 -std=c++11 std_bind1.cpp -o std_bind1
実行例
% ./std_bind1 void f1() void f2(int) 123 void f3(int, int) 467 789
std::bindで引数を束縛する例
std::bindでオブジェクトにあらかじめ、引数を束縛することができます。引数の1部を束縛し、ほかの引数は、呼び出し時に指定するなど柔軟に決められます。
ソースコード std_bind2.cpp
#include <iostream> #include <functional> void f2(int x) { std::cout << __PRETTY_FUNCTION__ << " " << x << std::endl; } void f3(int x, int y) { std::cout << __PRETTY_FUNCTION__ << " " << x << " " << y << std::endl; } int main(int argc, char const* argv[]) { auto func2 = std::bind(f2, 123); // 引数が1つ。1つの引数をバインドする。 func2(); // 呼び出し 123 auto func3 = std::bind(f3, 123, 456); // 引数が2つ。2つともバインドする。 func3(); // 呼び出し 123, 457 auto func4 = std::bind(f3, 789, std::placeholders::_1); // 引数が2つ、1つだけバインドする。 func4(1000); // 呼び出し: 789, 1000 return 0; }
コンパイル
g++49 -std=c++11 -I/usr/local/lib/gcc49/include/c++/ \ -Wl,-rpath=/usr/local/lib/gcc49 -std=c++11 std_bind2.cpp -o std_bind2
実行例
% ./std_bind2 void f2(int) 123 void f3(int, int) 123 456 void f3(int, int) 789 1000
std::bindで参照を束縛する例
ソースコード std_bind_ref1.cpp
std::bindで変数を参照渡しするには、std::refを併用します。 変数xをstd::bindの引数にただ指定するだけだと、値渡しになってしまいます。 std::ref()を使用することで参照渡しになります。 以下のコードでは、func()を実行した結果、f()内部で参照渡しの引数xが書き換えられ、main()に戻ったときに、main()のローカル変数xが変更されていることが確認できます。
#include <iostream> #include <functional> void f(int& x) { x = 123; } int main(int argc, char const* argv[]) { int x = 0; auto func = std::bind(f, std::ref(x) ); func(); std::cout<<x<<std::endl; return 0; }
コンパイル
g++49 -std=c++11 -I/usr/local/lib/gcc49/include/c++/ \ -Wl,-rpath=/usr/local/lib/gcc49 -std=c++11 std_bind_ref1.cpp -o std_bind_ref1
実行例
% ./std_bind_ref1 123
std::bindとplaceholdersで引数の順番を入れ替える例
placeholdersの_1,_2の順番を変えることで、bindしたオブジェクトを呼び出すときの引数の順番を変更できます。
ソースコード std_bind3.cpp
#include <iostream> #include <functional> void f3(int x, int y) { std::cout << __PRETTY_FUNCTION__ << " " << x << " " << y << std::endl; } int main(int argc, char const* argv[]) { auto func1 = std::bind(f3, std::placeholders::_1, std::placeholders::_2); auto func2 = std::bind(f3, std::placeholders::_2, std::placeholders::_1); func1(1,2); // f3(1,2)の意味 func2(1,2); // f3(2,1)の意味 return 0; }
コンパイル
g++49 -std=c++11 -I/usr/local/lib/gcc49/include/c++/ \ -Wl,-rpath=/usr/local/lib/gcc49 -std=c++11 std_bind3.cpp -o std_bind3
実行例
% ./std_bind3 void f3(int, int) 1 2 void f3(int, int) 2 1
std::bindでクラスのメンバ関数を束縛する例
ソースコード std_bind_class_member1.cpp
#include <iostream> #include <functional> using namespace std; class Foo { private: public: int data; Foo () :data(7) {} Foo (int _x) :data(_x) {} void display_hello () { cout << "Hello" << endl; } void display_number(int i) { cout << "Number: " << i << endl; } }; int main(int argc, char const* argv[]) { Foo foo1(123); auto f1 = std::bind(&Foo::display_number, foo1, 456); f1(); return 0; }
コンパイル
g++49 -std=c++11 -I/usr/local/lib/gcc49/include/c++/ \ -Wl,-rpath=/usr/local/lib/gcc49 -std=c++11 std_bind_class_member1.cpp -o std_bind_class_member1
実行例
% ./std_bind_class_member1 Number: 456
関連項目
- std::mem_fn
- std::bind
- std::ref
ツイート
スポンサーリンク