使用std::shared_ptr对象实例创建boost::thread

5

我有以下两个代码段。第一个块编译并按预期工作。然而,第二个块无法编译。

我的问题是,给定下面的代码,尝试基于被 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
2个回答

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_fn知道如何与std::shared_ptr交互。boost::thread t(std::mem_fn(&foo::boo), fptr);

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被要求可以与任何类似指针的类型一起使用,只需对其进行解引用即可,例如*fptr,但是boost::mem_fn则使用*boost::get_pointer(fptr)。我不知道它是否在最新版本的Boost中得到了修复,但我认为它应该使用SFINAE来检测get_pointer是否有效,否则应该直接对其进行解引用。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接