std ::関数呼び出し可能ラッパー
次のようにC ++の呼び出し可能(呼出可能オブジェクト)が定義されます。
- 関数ポインタ:C言語と一致。
- クラスのメンバ関数ポインタ。
- ファンクタ(ファンクタ)は:また、オブジェクトの関数として、過負荷
operator()
クラス/オペレーター構造オブジェクト。 - ラムダ式。
std ::関数が呼び出し可能オブジェクトのラッパー(ラッパー)、任意のクラスのメンバ関数ポインタに加えて受信することができる呼出可能オブジェクトです。std ::機能は、より多くの呼び出し可能オブジェクトを保存するために、それらの実行を遅らせることができるように、C言語の関数ポインタと同様に、コールバック関数を処理するために使用することができますが、それは、C言語よりも強力であるように、それは、関数ポインタに加えて、呼び出し可能オブジェクトを保存することがあります。
私たちははstd ::ときに関数が、それは呼んでこれらの機能のすべてを収容することができ、パッケージとなり(パラメータと戻り値のリストを含む関数型を、)関数のシグネチャをインスタンス化。
std ::機能の基本的な使い方
#include <iostream>
#include <functional> // std::function
// global function
void func(void) {
std::cout << __FUNCTION__ << std::endl;
}
class Foo {
public:
// class static function
static int foo_func(int a) {
std::cout << __FUNCTION__ << "(" << a << "):";
return a;
}
// class non-static member function
int foo_func_nonstatic(int a) {
std::cout << __FUNCTION__ << "(" << a << "):";
return a;
}
};
class Bar {
public:
// functor
int operator()(int a) {
std::cout << __FUNCTION__ << "(" << a << "):";
return a;
}
};
int main() {
// 传入合适函数签名给std::function模板参数即可绑定对应签名的
// 普通函数或
// 类静态成员函数或
// 借助std::bind绑定类非静态成员函数
std::function<void(void)> func1 = func;
std::function<int(int)> func2 = Foo::foo_func;
Foo foo;
std::function<int(int)> func3 = std::bind(&Foo::foo_func_nonstatic, &foo,
std::placeholders::_1);
// 然后,直接像函数一样调用
func1(); // func
std::cout << func2(1) << std::endl; // foo_func(1):1
std::cout << func3(11) << std::endl; // foo_func_nonstatic(11):11
// 当函数签名一致时,func2可像一个变量一样复用
// Bar重载了operator()即成为functor,可直接包装到std::function
Bar bar;
func2 = bar;
std::cout << func2(2) << std::endl; // operator()(2):2
// 也可绑定lambda表达式
auto func_lambda = [](int a){
std::cout << "bind lambda sample(" << a << ")" << std::endl;
};
func_lambda(3); // bind lambda sample(3)
return 0;
}
左関数値受信したオブジェクトとしてのstd ::機能するので、それはパラメータとして機能することができる。STD ::関数と関数ポインタを結合させることができ、機能の遅延実行を達成するために、それは置換されていてもよいのstd ::関数のstd ::関数コールバック関数として。
std ::の例として、以下を達成するための関数コールバック・メカニズム:
#include <iostream>
#include <functional> // std::function
// 任意可调用对象,如普通全局函数
void func_callback(int a) {
std::cout << __FUNCTION__ << ":Output, a=" << a << std::endl;
}
class Foo {
public:
explicit Foo(std::function<void(int)> cb)
:cb_(cb), a_(0) {
}
~Foo() = default;
// setter
void set_a(int a) {
a_ = a;
}
void OutputCallback() {
cb_(a_);
}
private:
std::function<void(int)> cb_;
int a_;
};
int main() {
// 实例化Foo,并参数注入回调函数
// 处理
// 回调输出处理结果
Foo foo(func_callback);
foo.set_a(1);
foo.OutputCallback(); // func_callback:Output, a=1
return 0;
}
上記、呼出可能オブジェクトをバインディングの使用のstd ::関数を記述し、例えばコールバック関数としてのstd ::関数のインスタンスを示すために、これは、そのような顔インテリジェント分析などの実用的な用途においてintへfunc_callbackコールバックパラメータ、コールバック関数のポインタ引数として構造解析情報面、機能月認識結果を出力する;クラスFooの人間の顔関連カテゴリは、OutputCallbackクラスはスレッド顔の分析とも呼ばれる、得られた結果の分析あなたはユーザーfunc_callbackのを提供するために、コールバックOutputCallback出力を呼び出すことができます。
注:C ++ 11のstd ::を提供する機能は、代わりにコールバックとしてC言語の関数ポインタで、前者は、CプログラミングスタイルであるC ++プログラミングスタイルです。
C / C ++コールバック機構同時サーバ側アプリケーションプログラムおよびゲームワイド、周知の広く使用されている2DゲームフレームワークCocos2dxコールバック機構、コールバック以下の一般的なマクロを提供し、コールバック機構は、よりオープンCocos2dx基準源であってもよいです。
// Cocos2dx new callbacks based on C++11
//
// __selector__:回调函数指针
// __target__:回调对象指针
// ##__VA_ARGS__:可变参数列表
// std::placeholders::_1:不定参数1,调用时由调用函数的参数传入
// std::placeholders::_2:不定参数2,调用时由调用函数的参数传入
// std::placeholders::_3:不定参数3,调用时由调用函数的参数传入
#define CC_CALLBACK_0(__selector__,__target__, ...) std::bind(&__selector__,__target__, ##__VA_ARGS__)
#define CC_CALLBACK_1(__selector__,__target__, ...) std::bind(&__selector__,__target__, std::placeholders::_1, ##__VA_ARGS__)
#define CC_CALLBACK_2(__selector__,__target__, ...) std::bind(&__selector__,__target__, std::placeholders::_1, std::placeholders::_2, ##__VA_ARGS__)
#define CC_CALLBACK_3(__selector__,__target__, ...) std::bind(&__selector__,__target__, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, ##__VA_ARGS__)
反省のstd ::機能/ STD ::バインドと抽象的な工場、ファクトリメソッド
TODO...