は、関数ポインタだけでなく、任意のオブジェクトのコピー全体を保持するboost::function
ことができ、仮想上で呼び出すことができますoperator()
。
それがどのように機能するかを理解するのに役立ちます(説明のために)。
以下は、boost::function
型トリックのおもちゃの実装です。
struct helper_base { virtual void do_it() = 0; };
template<typename Func>
struct helper:helper_base {
Func func;
helper(Func f):func(f) {}
virtual void do_it() override { func(); }
};
struct do_something_later {
boost::unique_ptr<helper_base> pImpl;
template<typename Func>
do_something_later( Func f ):pImpl(make_shared<helper<Func>>(f))
{}
void operator()() { (*pImpl).do_it(); }
private:
do_something_later( do_something_later const& ); // deleted
void operator=( do_something_later const& ); // deleted
};
ここで mydo_something_later
は任意のオブジェクト (Func) を取り、必要operator()
に応じてそれを呼び出します。呼び出しているものの型を型消去ヘルパーでラップし、仮想関数を介してoperator()
呼び出します。operator()
Func
type は関数ポインターである場合もあれば、状態を持つファンクターである場合もあります。operator() でコピー可能なものは何でも公正なゲームです。のユーザーdo_something_later
に関する限り、バイナリ インターフェイスは 1 つしかありません。
boost::function
(およびstd::function
)基本的にこれと同じ手法を(多くの改善を加えて)使用して、可能なインターフェイスのセット全体を1つのインターフェイスに変換します。コストには、関数の呼び出しvirtual
(または同等レベルの間接参照) が含まれます。