コード全体にマジックボックスが散在しているのは嫌いです... function <>のパラメータが完全に異なるパラメータが渡された場合でも、基本的にすべての関数を関数オブジェクトにマップできるようにするには、これら2つのクラスがどのように機能するのでしょうか。 boost::bind
さまざまな呼び出し規約でも機能します(つまり、メンバーメソッドは__thiscall
VCの下にありますが、「通常の」関数は通常、__cdecl
または__stdcall
Cとの互換性が必要な関数用です。
コード全体にマジックボックスが散在しているのは嫌いです... function <>のパラメータが完全に異なるパラメータが渡された場合でも、基本的にすべての関数を関数オブジェクトにマップできるようにするには、これら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
です。割り当てるオブジェクトのタイプごとに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); }
};
つまり、あなたの場合、ブースト機能への割り当ては次のようになります。
function_impl_concrete<void(int), unspecified_type>
(もちろん、コンパイル時です)関数オブジェクトを呼び出すと、実装オブジェクトの仮想関数が呼び出され、元の関数に呼び出されます。
免責事項:この説明の名前は意図的に構成されていることに注意してください。実在の人物やキャラクターとの類似点...あなたはそれを知っています。目的は、原則を説明することでした。
arg0) const=0 { return...
。...これまで見たことがありません。フォーラムで、純粋仮想関数に本体を含めることができることを説明するC ++のFAQにリンクされたフォローアップメッセージが機能しない例を見つけましたが、そのような構文(clang&gcc)を使用してコンパイルするコードを取得できません。
=0;
、後で与えられる本体で宣言されたときに本体を与えることができます(例えばvoid Base::Blah() { /* ... */ }
)...私は上記で使用されている表記法について具体的に尋ねています。単なるタイプミスだと思います。