2011-01-12 12 views
2

boost :: bindを使用して関数にパラメータをバインドするとき - 関数が必要とする型にキャストされるとき(暗黙のキャストが可能な場合)?boost :: bindはいつ引数を必要な型にキャストしますか?

どのようにbind_tオブジェクトに格納されますか?もともとバインドに渡された型、または関数の署名に必要な型として?具体

:私は署名

void SomeFun(SmartPointer<SomeType>) 

の機能を有し、私はsomePtrタイプSomeType*である

boost::bind(&SomeFun, somePtr) 

としてバインドを使用する場合

bind_tオブジェクトが含まれていますsomePtrのコピーが単純なポインタとして格納されているか、SmartPointer<SomeType>にキャストされ、s SmartPointer<SomeType>として転売しましたか?

SomeType*からSmartPointer<SomeType>への暗黙のキャストがあります。 boost::shared_ptrとは対照的に、このSmartPointerは管理対象オブジェクトの参照カウンタを使用します。つまり、SomeTypeSmartPointedから派生する必要があります。

答えて

2

SomeType *からのshared_ptrへの暗黙的な変換や暗黙のコンストラクタがないため、これは機能しません。

somePtrは、あなただけの「新しい」で割り当てられたとのshared_ptrの最後の参照がスコープの外に出たとき、後に削除されることを期待しているポインタである場合は、

boost::bind(&SomeFun, boost::shared_ptr<SomeType>(somePtr)) 

を呼び出す必要があります。ポインタを削除したくないが、呼び出し時にポインタが有効であり、関数がshared_ptrを取る必要があることがわかっている場合は、no-opディテクタを使用してshared_ptrを作成することができます。いずれにしても、これはshared_ptrであり、ポインタやweak_ptrなどではなく、このインスタンスで渡す必要があります。

あなたのケースは異なっているため、実際のケースまたはそれに近いケースを確認する必要があります。

渡す関数がクラスメンバ関数で、クラスインスタンス(オブジェクト)をパラメータの1つとして渡す場合は、混乱するかもしれません。ここでは、ポインタ、リファレンス、またはshared_ptrを渡すことができます。また、関数がconstメソッド(同様にポインタへのポインタまたはconstへのshared_ptr)である場合、その参照はconst参照になります。

これは、関数がクラスメンバ関数である場合、boost :: bindにはこれらすべてのオーバーロードが異なるためです。

変換が暗黙的に行われる場合、暗黙の変換は関数が呼び出された時点で行われます。 boost :: bindは、渡されたものを格納する単なるテンプレートです。 メンバ関数を呼び出すために使用される場合、最初のパラメータでいくつかのマジックが発生します。

boost :: bindは、関数が実際に参照を取得する場所であるboost :: refを格納することがあります。

+0

私はより密接に私の実際のケースを表現するために私の質問を更新しました。 –

+0

関連する部分は「変換が暗黙のうちに、関数が呼び出された時点で暗黙の変換が行われます。boost :: bindは、渡された内容を格納するテンプレートにすぎません。それは私の質問に答えます。 –

0

渡された型として格納されます。

バインドを実行したときにバインドで返された関数オブジェクトを呼び出すと、変換が実行されます。その後、あなたはブーストのこの振る舞い与えられた興味深いバグ::バインドになってしまっているだろう

template<class Y> 
explicit shared_ptr(Y * p): px(p), pn(p) // Y must be complete 

は、shared_ptrのコンストラクタを明示的にマークされていませんでした。ファンクタを一度だけ呼び出すと、すべてがうまくいってオブジェクトが削除されます。あなたが複数回呼び出すと、2回目のfree_ptrを作成したときにすでに解放されているポインタを使用していたので、2回目のフリーでuse-after-freeのバグが発生します。

(私はちょうど後押し理由についてrelated questionを尋ねた::バインドがこのように実装されている)

関連する問題