1. C言語における関数ポインタ
まず、関数ポインターのサンプル test_fun.cpp を見てください。
#include<iostream>
//定义函数指针
typedef int (*func)();
using namespace std;
int test1(){
cout<<"hello, test1"<<endl;
return 0;
}
int test2(){
cout<<"hello, test2"<<endl;
return 0;
}
int main(int argc, char * argv[]){
func fp = test1;
fp();
fp = test2;
fp();
return 0;
}
実行結果は以下の通りです。
2、std::functionの役割
実際、std::function の関数は上記の関数ポインタと似ています。
ただし、 std::function は関数ポインターよりも強力で、より多くのアプリケーション シナリオがあります。std::function は呼び出し可能なオブジェクト ラッパーであり、呼び出し可能なオブジェクトは次の条件のいずれかを満たします。
(1) 関数ポインタ
(2) Operator() メンバー関数 (レジェンダリー ファンクター)、ラムダ式を持つ
クラス オブジェクト (3) 関数ポインタに変換できるクラス オブジェクト
(4) クラス メンバー (関数) ポインタ
( 5) バインド式または他の関数オブジェクト
実際のプログラミングでは主に次のようなシナリオがあります。
(1) 関数(通常関数または静的関数)をバインドする
(2) コールバック関数を実装する
(3) 関数の入力パラメータとして
3. いくつかの例
1. 関数をバインドする
#include <iostream>
#include <functional>
using namespace std;
int test1(){
cout<<"hello, test1"<<endl;
return 0;
}
int main(int argc, char * argv[]){
std::function<int(void)> fr_test1 = test1;
fr_test1();
return 0;
}
2. コールバック関数として
#include <iostream>
#include <functional>
using namespace std;
class A{
function<void()> callback;
public:
A(){};
A(const function<void()>& f) : callback(f) {};
void notify(void){
callback();
}
void init(const function<void()>& f){
callback = f;
}
};
class Foo {
public:
// Foo foo;
// foo(); //此时会执行operator()方法
void operator()(void) {
cout << __FUNCTION__ << endl;
}
};
void test(){
cout << "test()" << endl;;
}
int main(void)
{
Foo foo;
A aa(foo);
aa.notify();
A bb;
bb.init(test);
bb.notify();
}
3. 関数の入力パラメータとして
#include <iostream>
#include <functional>
using namespace std;
void call_when_even(int x, const std::function<void(int)>& f) {
if (!(x & 1)) {
f(x);
}
}
void output(int x) {
cout << x << " ";
}
int main(void){
for (int i = 0; i < 10; ++i) {
call_when_even(i, output);
}
cout<<endl;
return 0;
}
参考: