C++

【C++】std::bindの使い方

More than 3 years have passed since last update.

C++のstd::bindの使い方。

使おうと思った時に忘れてるのでメモ。


main.cpp

#include <iostream>


void test_function(int a, int b) {
printf("a=%d, b=%d\n", a, b);
}

int main(int argc, const char * argv[]) {
auto func1 = std::bind(test_function, std::placeholders::_1, std::placeholders::_2);
func1(1, 2);
// -> a=1, b=2

auto func2 = std::bind(test_function, std::placeholders::_1, 9);
func2(1);
// -> a=1, b=9

return 0;
}


std::bindは何をしてくれるかというと、

指定した関数をラップしたstd::functionを作る

ということです。

std::placeholders::_nというのがわかりづらいですが、これは

作ったstd::functionを呼び出す時の引数

を表しています。

上の例の場合、こんな感じの関数(std::function)が作られると考えると良いと思います。(あくまでイメージ)

auto func1 = std::bind(test_function, std::placeholders::_1, std::placeholders::_2);

// こんなイメージの関数(std::function)ができる
void func1(?1, ?2) {
test_function(?1, ?2);
}

auto func2 = std::bind(test_function, std::placeholders::_1, 9);
// こんなイメージの関数(std::function)ができる
void func2(?1) {
test_function(?1, 9);
}

?1, ?2 と書いたのは std::placeholdersを表しています。

func2の例の場合は、2つ目の引数を固定値にしているので、実行時に固定値が渡されます。

std:: placeholdersは最初は理解しづらいですが、プログラムからSQLを実行する際の、

"?" をイメージすると良いかもしれません。

select * from table_name where id=?;

と書いた時のバインド変数 "?" がstd::placeholders::_1にあたります。


この定義したSQLがstd::bindの戻り値(std::function)で、SQL(std::function)を実行する時に、

"?" (std::placeholders)に引数を渡して呼び出すという感じです。

ちなみにインスタンスメソッドを指定したい場合は、std::bindの第2引数にインスタンスを渡します。


main.cpp

#include <iostream>


class Test {
public:
void test_function(int a, int b) {
printf("a=%d, b=%d\n", a, b);
}
};

int main(int argc, const char * argv[]) {
auto test = Test();
auto func1 = std::bind(&Test::test_function, test, std::placeholders::_1, std::placeholders::_2);
func1(1, 2);

return 0;
}


自分自身のメソッドを呼び出す場合はthisを指定すればOK。


main.cpp

#include <iostream>


class Test {
public:
void test_function(int a, int b) {
printf("a=%d, b=%d\n", a, b);
}

void bind_test() {
auto func1 = std::bind(&Test::test_function, this, std::placeholders::_1, std::placeholders::_2);
func1(1, 2);
}
};

int main(int argc, const char * argv[]) {

auto test = Test();
test.bind_test();

return 0;
}


以上です。