「std::bind」の版間の差分

提供: C++入門
移動: 案内検索
(ページの作成:「std::bind とは、functionの引数を束縛し、新しいオブジェクトを生成します。 '''読み方''' ;std::bind:えすてぃーでぃー ばい...」)
 
(相違点なし)

2014年2月15日 (土) 16:58時点における最新版

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

関連項目