2012-07-23 80 views
5

我有以下兩個代碼段。第一個模塊按預期進行編譯和工作。但是第二個塊不能編譯。使用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_ptrstd::mem_fn。後者的作品,因爲std::mem_fn知道如何(<boost/mem_fn.hpp>被包括在內)與std::shared_ptr

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

+0

非常好,工作正常!謝謝。 – 2012-07-23 01:26:52

3

戴夫小號的答案另一種方法是定義這個互動:

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是否可以正常工作,並且應該解除引用。

相關問題