5

次の2つのコードセグメントがあります。最初のブロックはコンパイルされ、期待どおりに機能します。ただし、2番目のブロックはコンパイルされません。

私の質問は、以下のコードを考えると、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
4

2 に答える 2

9

問題は、メンバー関数の処理にboost::thread依存していること、および(または少なくとも使用しているバージョン)が、使用することを期待しているメンバー関数または他の無数のスマートポインターの1つを呼び出すためにを使用する方法を知らないことです。エラーリストに入力します。boost::mem_fnboost::mem_fnstd::shared_ptrboost::shared_ptr

boost::mem_fnすでにそのオーバーロードがあるため、rawポインタは機能します。boost::shared_ptr解決策は、またはを使用することstd::mem_fnです。後者はstd::mem_fn、対話する方法を知っているために機能しますstd::shared_ptr

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

于 2012-07-23T01:23:25.973 に答える
3

Dave 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

C ++ 11ではstd::mem_fn、ポインタのような型を操作するには、単純にそれを逆参照する必要があります。つまり*fptrboost::mem_fn代わりに。を使用し*boost::get_pointer(fptr)ます。Boostの最新バージョンで修正されているかどうかはわかりませんが、SFINAEを使用して機能するかどうかを検出get_pointerし、そうでない場合は逆参照する必要があると主張します。

于 2012-07-23T09:01:52.110 に答える