Boost logo

Boost :

Subject: Re: [boost] [thread] using Boost.Thread with move-only arguments
From: Vicente J. Botet Escriba (vicente.botet_at_[hidden])
Date: 2013-04-07 19:16:43


Le 08/04/13 00:59, Fernando Pelliccioni a écrit :
> On Sun, Apr 7, 2013 at 7:36 PM, Vicente J. Botet Escriba <
> vicente.botet_at_[hidden]> wrote:
>
>> Le 08/04/13 00:33, Vicente J. Botet Escriba a écrit :
>>
>> Le 08/04/13 00:15, Fernando Pelliccioni a écrit :
>>>> On Thu, Apr 4, 2013 at 3:19 AM, Vicente J. Botet Escriba <
>>>> vicente.botet_at_[hidden]> wrote:
>>>>
>>>> Le 04/04/13 04:40, Fernando Pelliccioni a écrit :
>>>>> Hi Vicente,
>>>>>
>>>>>> I have an issue with Boost.Thread contructor using move-only type
>>>>>> arguments.
>>>>>>
>>>>>> The "Thread Constructor with arguments" section of the documentation
>>>>>> says
>>>>>> ...
>>>>>>
>>>>>> template <class F,class A1,class A2,...>
>>>>>> thread(F f,A1 a1,A2 a2,...);
>>>>>>
>>>>>> Preconditions:
>>>>>> F and each An must by copyable or movable.
>>>>>>
>>>>>> http://www.boost.org/doc/libs/****1_53_0/doc/html/thread/**thread_**_**>
>>>>>> management.html#thread.thread_****management.thread.multiple_****
>>>>>> argument_constructor<
http://**www.boost.org/doc/libs/1_53_0/**
>>>>>> doc/html/thread/thread_**management.html#thread.thread_**
>>>>>> management.thread.multiple_**argument_constructor<http://www.boost.org/doc/libs/1_53_0/doc/html/thread/thread_management.html#thread.thread_management.thread.multiple_argument_constructor>>
>>>>>>
>>>>>>
>>>>>> "An" could be copyable or movable, but the following example fails to
>>>>>> compile...
>>>>>>
>>>>>> error: use of deleted function 'A::A(const A&)'
>>>>>>
>>>>>> Sorry, if the documentation is not clear. I should add a link to
>>>>>> the
>>>>>>
>>>>> Move emulation section (http://www.boost.org/doc/**
>>>>> libs/1_53_0/doc/html/thread/****emulations.html#thread.****
>>>>> emulations.move<http://www.**boost.org/doc/libs/1_53_0/doc/**
>>>>> html/thread/emulations.html#**thread.emulations.move<http://www.boost.org/doc/libs/1_53_0/doc/html/thread/emulations.html#thread.emulations.move>>)
>>>>>
>>>>> for each function having rvalue references if the documentation is not
>>>>> clear. Please could you create a Ticket for that?
>>>>>
>>>>> Which Boost.Thread version are you using? That is, BOOST_THREAD_VERSION
>>>>> is
>>>>> 2, 3 or 4?
>>>>> Could you try by defining BOOST_THREAD_USES_MOVE, BOOST_THREAD_VERSION 3
>>>>> or BOOST_THREAD_VERSION 4?
>>>>>
>>>>>
>>>>>
>>>>>> I think we should modify ...
>>>>>>
>>>>>> template <class F,class A1>
>>>>>> thread(F f,A1 a1,typename
>>>>>> disable_if<boost::thread_****detail::is_convertible<F&,****thread_attributes
>>>>>>
>>>>>>
>>>>>>> ,
>>>>>>>
>>>>>> dummy* >::type=0):
>>>>>> thread_info(make_thread_info(****boost::bind(boost::type<void>**(**
>>>>>> ),f,a1)))
>>>>>> {
>>>>>> start_thread();
>>>>>> }
>>>>>>
>>>>>>
>>>>>> ... by ...
>>>>>>
>>>>>> template <class F,class A1>
>>>>>> thread(F&& f,A1&& a1,typename
>>>>>> disable_if<boost::thread_****detail::is_convertible<F&,****thread_attributes
>>>>>>
>>>>>>
>>>>>>> ,
>>>>>>>
>>>>>> dummy* >::type=0):
>>>>>>
>>>>>> thread_info(make_thread_info(****boost::bind(boost::type<void>**(**
>>>>>> ),f,boost::forward<A1>(a1))))
>>>>>> {
>>>>>> start_thread();
>>>>>> }
>>>>>>
>>>>>> ( In the all family of related ctors in "boost/thread/detail/thread.**
>>>>>> **hpp"
>>>>>> )
>>>>>>
>>>>>> But, I don't know if boost::bind is forwarding its arguments
>>>>>>
>>>>>> No. The problem is that boost::bind doesn't supports move semantics
>>>>> (Boost.Move).
>>>>>
>>>>> I think we should modify Boost.Bind to be similar to std::bind.
>>>>>
>>>>>> Is there any reason why Bind has not changed so far? Have you found any
>>>>>> limitations?
>>>>>>
>>>>>> IIRC, I requested the feature long-long time ago.
>>>>>
>>>>> If Bind can not be changed, I think Boost.Thread should use some other
>>>>>> tool
>>>>>> similar to Bind to make forwarding parameters.
>>>>>> GCC Libstdc++ use a Bind-lite tool for std::thread.
>>>>>>
>>>>>> I have taken in account some cases, but not everything works yet. E.g
>>>>> the
>>>>> prototype that you need is
>>>>>
>>>>> template <class F>
>>>>> explicit thread(BOOST_THREAD_RV_REF(F) f
>>>>> , typename disable_if<is_same<typename decay<F>::type, thread>,
>>>>> dummy* >::type=0
>>>>> );
>>>>>
>>>>> I suspect that you need to follow the instructions given in
>>>>> http://www.boost.org/doc/libs/****1_53_0/doc/html/thread/****>
>>>>> emulations.html#thread.****emulations.move.portable<http:**
>>>>> //www.boost.org/doc/libs/1_53_**0/doc/html/thread/emulations.**
>>>>> html#thread.emulations.move.**portable<
http://www.boost.org/doc/libs/1_53_0/doc/html/thread/emulations.html#thread.emulations.move.portable>>to
>>>>> make your class A movable :(
>>>>>
>>>>> I can work on this if you want.
>>>>>
>>>>>> What do you think?
>>>>>>
>>>>>> I'm all for a boost::bind or boost::bind-lite supporting boost
>>>>>> semantics
>>>>>>
>>>>> (using Boost.Move). If you can work on this a propose a patch to boost
>>>>> bind
>>>>> I'm sure all the Boost community will thank you.
>>>>> There are a lot of basic Boost libraries that need an update to support
>>>>> move semantics (as Tuple, Fusion, SmartPtr, Exception?) so that other
>>>>> libraries can built on them. Any effort on this sens will be much
>>>>> appreciated.
>>>>>
>>>>> Please, let me know if you have some trouble after defining one of the
>>>>> following
>>>>>
>>>>> #define BOOST_THREAD_USES_MOVE
>>>>> #define BOOST_THREAD_VERSION 3
>>>>> #define BOOST_THREAD_VERSION 4
>>>>>
>>>>> Best,
>>>>> Vicente
>>>>>
>>>>> ______________________________****_________________
>>>>> Unsubscribe & other changes: http://lists.boost.org/**
>>>>> mailman/listinfo.cgi/boost<htt**p://lists.boost.org/mailman/**
>>>>> listinfo.cgi/boost <http://lists.boost.org/mailman/listinfo.cgi/boost>>
>>>>>
>>>>>
>>>>>
>>>> Hi Vicente,
>>>>
>>>> I had not set BOOST_THREAD_VERSION. I just realized that is set to 2 by
>>>> default.
>>>> Sorry, I had no idea about Boost Thread Move emulations. I tested the
>>>> code
>>>> using a C++11 movable-only type and a Boost.Move movable-only type.
>>>>
>>>> Same compilation error if I define BOOST_THREAD_USES_MOVE and
>>>> BOOST_THREAD_VERSION to 3 or 4 ( using Boost Thread Move Emulation )
>>>>
>>>> #define BOOST_THREAD_USES_MOVE
>>>> //#define BOOST_THREAD_VERSION 3
>>>> #define BOOST_THREAD_VERSION 4
>>>>
>>>> #include <iostream>
>>>> #include <boost/thread.hpp>
>>>>
>>>> struct A
>>>> {
>>>> BOOST_THREAD_MOVABLE_ONLY(A)
>>>>
>>>> A() {}
>>>>
>>>> void run() { }
>>>> };
>>>>
>>>>
>>>> void f( A a )
>>>> {
>>>> a.run();
>>>> }
>>>>
>>>> void exec_boost()
>>>> {
>>>> A a;
>>>> boost::thread t( f, std::move(a) );
>>>> t.join();
>>>> }
>>>>
>>>> error: use of deleted function 'A::A(const A&)'
>>>>
>>>> I'll wok on Boost.Bind trying to make it move-enabled.
>>>>
>>>> Thank you for your dedication and patience.
>>>>
>>> You are welcome.
>>>
>>> Could you try with
>>>
>>> class A : public noncopyable
>>> {
>>> BOOST_THREAD_MOVABLE_ONLY(A)
>>>
>>> public:
>>> A(int ) {}
>>>
>>> A(BOOST_THREAD_RV_REF(A) ) {}
>>>
>>> A& operator=(BOOST_THREAD_RV_REF(**A) ) { return *this;}
>>>
>>> };
>>>
>>> BOOST_THREAD_DCL_MOVABLE_BEG(**T) A BOOST_THREAD_DCL_MOVABLE_END
>>>
>>>
>>> Sorry I meant
>>
>> BOOST_THREAD_DCL_MOVABLE(A)
>>
>>
>> Vicente
>>
>>
>>
>> ______________________________**_________________
>> Unsubscribe & other changes: http://lists.boost.org/**
>> mailman/listinfo.cgi/boost<http://lists.boost.org/mailman/listinfo.cgi/boost>
>>
>
>
> Hi Vicente,
>
> Same error...
>
> //Begin code ------------------------------------------------------
> #define BOOST_THREAD_USES_MOVE
> //#define BOOST_THREAD_VERSION 3
> #define BOOST_THREAD_VERSION 4
>
> #include <boost/thread.hpp>
>
> class A : public boost::noncopyable
> {
> BOOST_THREAD_MOVABLE_ONLY(A)
>
> public:
> A( int ) {}
>
> A(BOOST_THREAD_RV_REF(A) ) {}
> A& operator=(BOOST_THREAD_RV_REF(A) ) { return *this; }
>
> void run() { }
> };
>
> //BOOST_THREAD_DCL_MOVABLE_BEG(T) A BOOST_THREAD_DCL_MOVABLE_END
> BOOST_THREAD_DCL_MOVABLE(A)
>
> void f( A a )
> {
> a.run();
> }
>
> void exec_boost()
> {
> A a(1);
> boost::thread t( f, std::move(a) );
> //t.join();
> }
>
> //End code ------------------------------------------------------
>
>
> The error occurs in
> boost/thread/detail/thread.hpp
> line 389
> Trunk revision 83652
>
> template <class F,class A1>
> thread(F f,A1 a1,typename
> disable_if<boost::thread_detail::is_convertible<F&,thread_attributes >,
> dummy* >::type=0):
> line 389:
> thread_info(make_thread_info(boost::bind(boost::type<void>(),f,a1)))
> {
> start_thread();
> }
>
>
> parameter a1 is not a BOOST_THREAD_RV_REF(A1) and is not moved.
>
> I think it should be:
>
> template <class F,class A1>
> thread(F f, BOOST_THREAD_RV_REF(A1) a1,typename
> disable_if<boost::thread_detail::is_convertible<F&,thread_attributes >,
> dummy* >::type=0):
> line 389:
> thread_info(make_thread_info(boost::bind(boost::type<void>(),f,
> boost::move(a1) )))
> {
> start_thread();
> }
>
> But in this case the error will occur within Boost.Bind
>
>
With which compiler?

Vicente


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk