2012-07-23 15 views
5

次の2つのコードセグメントがあります。最初のブロックはコンパイルされ、期待どおりに動作します。しかし、2番目のブロックはコンパイルされません。std :: shared_ptrオブジェクトインスタンスを使ったboost :: threadの作成

私の質問は、shared_ptrによってプロキシされているオブジェクトのインスタンスに基づいてスレッドを作成しようとすると、正しい構文は何ですか?

#include <iostream> 
#include <new> 
#include <memory> 

#include <boost/thread.hpp> 

struct foo 
{ 
    void boo() {} 
}; 

int main() 
{ 
    //This works 
    { 
     foo* fptr = new foo; 
     boost::thread t(&foo::boo,fptr); 
     t.join(); 
     delete fptr; 
    } 

    //This doesn't work 
    { 
     std::shared_ptr<foo> fptr(new foo); 
     boost::thread t(&foo::boo,fptr); 
     t.join(); 
    } 

    return 0; 
} 

コンパイラエラー:

Error 5 error C2784: 'T *boost::get_pointer(T *)' : could not deduce template argument for 'T *' from 'std::tr1::shared_ptr<_Ty>' c:\program files (x86)\boost\boost_1_47\boost\bind\mem_fn_template.hpp 40 1 htest 
Error 3 error C2784: 'T *boost::get_pointer(const std::auto_ptr<_Ty> &)' : could not deduce template argument for 'const std::auto_ptr<_Ty> &' from 'std::tr1::shared_ptr<_Ty>' c:\program files (x86)\boost\boost_1_47\boost\bind\mem_fn_template.hpp 40 1 htest 
Error 4 error C2784: 'T *boost::get_pointer(const std::auto_ptr<_Ty> &)' : could not deduce template argument for 'const std::auto_ptr<_Ty> &' from 'std::tr1::shared_ptr<_Ty>' c:\program files (x86)\boost\boost_1_47\boost\bind\mem_fn_template.hpp 40 1 htest 
Error 8 error C2784: 'T *boost::get_pointer(const boost::shared_ptr<X> &)' : could not deduce template argument for 'const boost::shared_ptr<X> &' from 'std::tr1::shared_ptr<_Ty>' c:\program files (x86)\boost\boost_1_47\boost\bind\mem_fn_template.hpp 40 1 htest 
Error 9 error C2784: 'T *boost::get_pointer(const boost::shared_ptr<X> &)' : could not deduce template argument for 'const boost::shared_ptr<X> &' from 'std::tr1::shared_ptr<_Ty>' c:\program files (x86)\boost\boost_1_47\boost\bind\mem_fn_template.hpp 40 1 htest 
Error 1 error C2784: 'T *boost::get_pointer(const boost::scoped_ptr<T> &)' : could not deduce template argument for 'const boost::scoped_ptr<T> &' from 'std::tr1::shared_ptr<_Ty>' c:\program files (x86)\boost\boost_1_47\boost\bind\mem_fn_template.hpp 40 1 htest 
Error 2 error C2784: 'T *boost::get_pointer(const boost::scoped_ptr<T> &)' : could not deduce template argument for 'const boost::scoped_ptr<T> &' from 'std::tr1::shared_ptr<_Ty>' c:\program files (x86)\boost\boost_1_47\boost\bind\mem_fn_template.hpp 40 1 htest 
Error 6 error C2784: 'T *boost::get_pointer(const boost::reference_wrapper<T> &)' : could not deduce template argument for 'const boost::reference_wrapper<T> &' from 'std::tr1::shared_ptr<_Ty>' c:\program files (x86)\boost\boost_1_47\boost\bind\mem_fn_template.hpp 40 1 htest 
Error 7 error C2784: 'T *boost::get_pointer(const boost::reference_wrapper<T> &)' : could not deduce template argument for 'const boost::reference_wrapper<T> &' from 'std::tr1::shared_ptr<_Ty>' c:\program files (x86)\boost\boost_1_47\boost\bind\mem_fn_template.hpp 40 1 htest 
Error 10 error C2784: 'T *boost::get_pointer(const boost::intrusive_ptr<T> &)' : could not deduce template argument for 'const boost::intrusive_ptr<T> &' from 'std::tr1::shared_ptr<_Ty>' c:\program files (x86)\boost\boost_1_47\boost\bind\mem_fn_template.hpp 40 1 htest 
Error 11 error C2784: 'T *boost::get_pointer(const boost::intrusive_ptr<T> &)' : could not deduce template argument for 'const boost::intrusive_ptr<T> &' from 'std::tr1::shared_ptr<_Ty>' c:\program files (x86)\boost\boost_1_47\boost\bind\mem_fn_template.hpp 40 1 htest 

答えて

9

問題はboost::threadは、メンバ関数を処理するためにboost::mem_fnに依存している、とboost::mem_fnは(あるいは、少なくとも、あなたが使用しているバージョン)を使用する方法を知らないということですstd::shared_ptrを使用して、boost::shared_ptrを使用するか、エラーリストに無数のスマートポインタタイプを使用すると期待しているので、メンバー関数を呼び出すことができます。

boost::mem_fnに既にそのオーバーロードがあるため、未加工のポインタが機能します。ソリューションはboost::shared_ptrまたはstd::mem_fnを使用します。後者の作品std::mem_fnstd::shared_ptr

boost::thread t(std::mem_fn(&foo::boo), fptr);

+0

優れています。ありがとうございました。 –

3

とデイブSの答えの代わりに対話する方法を知っているので、この(<boost/mem_fn.hpp>前には含まれます)を定義することです: "教える" ということ

namespace boost 
{ 
    template<typename T> 
    inline T* 
    get_pointer(const std::shared_ptr<T>& p) 
    { return p.get(); } 
} 

boost::mem_fnを使用して、std::shared_ptrから未処理のポインタを取得します。 ++ 11 std::mem_fn Cで

は単に即ち*fptrを逆参照することにより、任意のポインタのような形で動作する必要はなく、boost::mem_fn代わり*boost::get_pointer(fptr)を使用しています。 Boostの最新バージョンで修正されているかどうかは分かりませんが、get_pointerが動作するかどうかを検出するにはSFINAEを使用する必要があります。

関連する問題