Boost logo

Boost :

Subject: Re: [boost] [thread] using Boost.Thread with move-only arguments
From: Fernando Pelliccioni (fpelliccioni_at_[hidden])
Date: 2013-04-07 19:37:51


El abr 7, 2013 8:17 PM, "Vicente J. Botet Escriba" <vicente.botet_at_[hidden]>
escribió:
>
> 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_**
<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/**<
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?
>
>

MinGW - GCC 4.7.1
MinGW - GCC 4.7.2


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