
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@wanadoo.fr> 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@wanadoo.fr> 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.
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
If Bind can not be changed, I think Boost.Thread should use some other 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? Vicente