私はコード全体に魔法の箱が散らばっているのが嫌いです...関数<>に渡されるものとまったく異なるパラメータが設定されている場合でも、これらの2つのクラスがどのように機能して基本的にすべての関数を関数オブジェクトにマッピングできるかboost::bind
異なる呼び出し規約でも動作します(つまり、メンバーメソッドは__thiscall
VCの下で、しかし「通常の」関数は一般に__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
から派生した具象クラスです。 boost::function
に割り当てるオブジェクトのタイプごとに1つあります
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); }
};
それはあなたの場合、ブースト機能への割り当てを意味します:
function_impl_concrete<void(int), unspecified_type>
をインスタンス化します(もちろんコンパイル時間です)関数オブジェクトを呼び出すと、実装オブジェクトの仮想関数が呼び出され、元の関数への呼び出しが指示されます。
免責事項:この説明の名前は意図的に構成されていることに注意してください。実在の人物やキャラクターとの類似点は...知っています。目的は、原理を説明することでした。