我有以下两个代码段。第一个块编译并按预期工作。但是第二个块不能编译。
我的问题是,根据下面的代码,在尝试基于被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
答案 0 :(得分:9)
问题是boost::thread
依赖boost::mem_fn
来处理成员函数,boost::mem_fn
(或者至少你正在使用的版本)不知道如何使用std::shared_ptr
boost::shared_ptr
1}}调用一个成员函数,因为它希望你在错误列表中使用boost::mem_fn
或无数其他智能指针类型之一。
原始指针有效,因为boost::shared_ptr
已经有了这个重载。解决方案是使用std::mem_fn
或std::mem_fn
。后者有效,因为std::shared_ptr
知道如何与boost::thread t(std::mem_fn(&foo::boo), fptr);
{{1}}
答案 1 :(得分:3)
Dave S回答的另一种方法是定义它( {<1>}之前的):
<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
获取原始指针。
在C ++ 11中std::shared_ptr
需要使用任何类似指针的类型,只需解除引用即std::mem_fn
,但*fptr
使用boost::mem_fn
。我不知道它是否已在最新版本的Boost中修复,但我认为它应该使用SFINAE来检测*boost::get_pointer(fptr)
是否有效,并且应该仅取消引用它。