[解決済み] boost::functionとboost::bindのしくみ
質問
私は自分のコードにマジックボックスが散らばっているのが嫌いです。この2つのクラスは、基本的にどんな関数でも関数オブジェクトにマッピングすることができ、たとえ関数が私が渡すものと全く異なるパラメータセットを持っていても、正確にどのように機能するのでしょうか。
boost::bind
さらに、異なる呼び出し規則でも動作します (例えば、メンバーメソッドが
__thiscall
であるのに対し、通常の関数は一般に
__cdecl
または
__stdcall
で、Cとの互換性が必要なものには
どのように解決するのですか?
boost::function
であれば、何でも
operator()
を使えば、正しいシグネチャのものをパラメータとしてバインドすることができ、バインドの結果はパラメータ
int
にバインドすることができます。
function<void(int)>
.
このような仕組みになっています(この記述は
std::function
):
boost::bind(&klass::member, instance, 0, _1)
はこのようなオブジェクトを返します。
struct unspecified_type
{
... some members ...
return_type operator()(int i) const { return instance->*&klass::member(0, i);
}
ここで
return_type
と
int
のシグネチャから推測されます。
klass::member
そして、関数ポインタとバインドされたパラメータは実際にはオブジェクトに格納されていますが、それは重要ではありません。
では
boost::function
は型チェックを行いません。どんなオブジェクトでも、そしてあなたがテンプレートパラメータで提供したどんなシグネチャでも受け取り、あなたのシグネチャに従って呼び出し可能なオブジェクトを作成し、そのオブジェクトを呼び出すのです。それが不可能な場合は、コンパイルエラーになります。
boost::function
は実際にはこのようなオブジェクトです。
template <class Sig>
class function
{
function_impl<Sig>* f;
public:
return_type operator()(argument_type arg0) const { return (*f)(arg0); }
};
ここで
return_type
と
argument_type
から抽出されます。
Sig
であり
f
はヒープ上に動的に確保されます。これは、サイズの異なる全く関係のないオブジェクトが
boost::function
.
function_impl
は単なる抽象クラス
template <class Sig>
class function_impl
{
public:
virtual return_type operator()(argument_type arg0) const=0;
};
すべての作業を行うクラスは
boost::function
. に割り当てるオブジェクトの種類ごとに 1 つ存在します。
boost::function
template <class Sig, class Object>
class function_impl_concrete : public function_impl<Sig>
{
Object o
public:
virtual return_type operator()(argument_type arg0) const=0 { return o(arg0); }
};
つまり、あなたの場合、boost関数への代入です。
-
は型をインスタンス化し
function_impl_concrete<void(int), unspecified_type>
(もちろんコンパイル時の話です) - ヒープ上にその型の新しいオブジェクトを作成します。
- このオブジェクトをboost::functionのfメンバに代入します。
関数オブジェクトを呼び出すと、その実装オブジェクトの仮想関数が呼び出され、元の関数への呼び出しが指示されます。
免責事項: この説明の中の名前は意図的に作られたものであることに注意してください。実在の人物やキャラクターに類似している場合は......おわかりですね。目的は原理を説明することでした。
関連
-
[解決済み】LLVMで暗黙のうちに削除されたコピーコンストラクタの呼び出し
-
[解決済み] string does not name a type Errorが発生するのはなぜですか?
-
[解決済み】C++エラー:の初期化に一致するコンストラクタがありません。
-
[解決済み】浮動小数点数の乱数生成
-
[解決済み] UbuntuにBoostをインストールする方法
-
[解決済み] 文字列の単語を反復処理するにはどうすればよいですか?
-
[解決済み] 1ビットのセット、クリア、トグルはどのように行うのですか?
-
[解決済み] static_cast, dynamic_cast, const_cast, reinterpret_cast はいつ使うべきですか?
-
[解決済み] コピーアンドスワップ慣用句とは?
-
[解決済み] C++11では、標準化されたメモリモデルが導入されました。その意味するところは?そして、C++プログラミングにどのような影響を与えるのでしょうか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】構造体のベクター初期化について
-
[解決済み】C++でランダムな2倍数を生成する
-
[解決済み】C++ 式はポインタからオブジェクトへの型を持っている必要があります。
-
[解決済み] string does not name a type Errorが発生するのはなぜですか?
-
[解決済み] 既に.objで定義されている-二重包含はない
-
[解決済み] 解決済み] `pthread_create' への未定義の参照 [重複] [重複
-
[解決済み】C++ - ステートメントがオーバーロードされた関数のアドレスを解決できない。
-
[解決済み】警告 - 符号付き整数式と符号なし整数式の比較
-
[解決済み] 警告:暗黙の定数変換でのオーバーフロー
-
[解決済み] 変数サイズのオブジェクトが初期化されないことがある c++