2012-07-23 7 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_ptrboost::shared_ptr 또는 오류 목록에 무수히 많은 다른 스마트 포인터 유형 중 하나를 사용할 것으로 예상하므로 멤버 함수를 호출합니다.

boost::mem_fn에 이미 해당 오버로드가 있기 때문에 원시 포인터가 작동합니다. 해결책은 boost::shared_ptr 또는 std::mem_fn입니다. 후자의 작품 std::mem_fn은 (<boost/mem_fn.hpp> 전에 포함됩니다) std::shared_ptr

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

+0

훌륭합니다. 고맙습니다. –

3
데이브 S의 대답에 대한 대안이를 정의하는 것입니다

와 상호 작용하는 방법을 알고 있기 때문에 :

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의 최신 버전에서 수정되었는지는 모르겠지만, get_pointer이 작동하는지 여부를 감지하려면 SFINAE를 사용해야한다고 주장하며, 그렇지 않은 경우에는 역 참조해야합니다.

관련 문제