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 18:33:48


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>
>>>
>>> "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>)
>> 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>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<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

Vicente


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