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

Creating boost::thread with an std::shared_ptr object instance

本文关键字:实例 创建 boost 对象 线程 ptr std shared 使用      更新时间:2023-10-16

我有以下两个代码段。第一个块按预期进行编译和工作。但是,第二个块不编译。

我的问题是,给定下面的代码,当试图基于由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)boostboost_1_47boostbindmem_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)boostboost_1_47boostbindmem_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)boostboost_1_47boostbindmem_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)boostboost_1_47boostbindmem_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)boostboost_1_47boostbindmem_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)boostboost_1_47boostbindmem_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)boostboost_1_47boostbindmem_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)boostboost_1_47boostbindmem_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)boostboost_1_47boostbindmem_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)boostboost_1_47boostbindmem_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)boostboost_1_47boostbindmem_fn_template.hpp  40  1   htest

问题是boost::thread依赖于boost::mem_fn来处理成员函数,而boost::mem_fn(或者至少是您正在使用的版本)不知道如何使用std::shared_ptr来调用成员函数,因为它希望您使用boost::shared_ptr或错误列表中无数其他智能指针类型之一。

原始指针可以工作,因为boost::mem_fn已经具有该重载。解决方案是使用boost::shared_ptrstd::mem_fn。后者之所以有效,是因为std::mem_fn知道如何与std::shared_ptr 交互

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

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_fnstd::shared_ptr获得原始指针。

在C++11中,std::mem_fn需要处理任何类似指针的类型,只需取消对其的引用,即*fptr,但boost::mem_fn使用*boost::get_pointer(fptr)。我不知道在最新版本的Boost中是否修复了它,但我认为它应该使用SFINAE来检测get_pointer是否有效,否则应该取消引用它。