Le 08/04/12 17:18, Jeffrey Lee Hellrung, Jr. a écrit :
On Sun, Apr 8, 2012 at 5:46 AM, Vicente J. Botet Escriba <vicente.botet@wanadoo.fr> wrote:
Le 07/04/12 11:11, John M. Dlugosz a écrit :
On 4/6/2012 11:59 AM, Vicente J. Botet Escriba wrote:
As you are using std::move, &&, ... why not using directly the C++11 Thread library
provided with the compiler?

1) VS10 has && and std::move, but does not have the C++11 threading library.
 1b) A naive implementation (just starts a new OS thread) is not wanted.
 1c) but, an overly heavy implementation is not wanted either (i.e VS11 beta), because of additional dependencies in the program to distribute.
2) In the final code, the && will be optional, to avoid copies on compilers that support it, but must work with compilers that don't.
3) I need to preserve semantics of the code I'm replacing with modern C++ forms.
OK, I see.


BTW, Boost.Thread could not implement async using Boost, as Boost.Tuple, Boost.Bind
Boost.Fusion (Tuple) because these libraries dont manage with rvalue references.

I don't understand how that applies to my compiler problem.  It's telling me that

          task_object(F const& f_);   // << refers to look here
          task_object(F&& f_);         // <<<< Error here

are not a valid overloading set and instead conflict.

Sorry, I misunderstood your message.

After applying the following patch your example compiles. Please could you try it?

Could you also add a Trac ticket so that this is tracked?

HTH,
Vicente

Vicente,

It looks like you're just removing the task_object::task_object(F const &) overload. Seems strange that this overload existed but was/is never actually suppose to be used. ...except when F is a function pointer, I guess???
You are right. It is necessary at least when Boost.Thread uses Boost.Move. I have added it only in this case.

I sent a message to the list recently observing that one problem was the binding of F to be an lvalue reference (according to the error message, AFAICS), meaning that "F const &" and "F&&" are exactly the same type. Perhaps this behavior should be addressed directly?


Next follows the best I could reach. Please, let me know if you see something wrong.

Thanks,
Vicente

P.S. Please don't apply this patch. I have removed some comments so it should not be applicable as such. I will commit it soon.
 
svn diff  boost/thread/future.hpp
Index: boost/thread/future.hpp
===================================================================
--- boost/thread/future.hpp    (revision 77840)
+++ boost/thread/future.hpp    (working copy)
@@ -1695,14 +1695,27 @@
             task_base<R>
         {
             F f;
-            task_object(F const& f_):
+#ifndef BOOST_NO_RVALUE_REFERENCES
+            task_object(R(*f_)()):
                 f(f_)
             {}
-#ifndef BOOST_NO_RVALUE_REFERENCES
             task_object(F&& f_):
+              f(boost::forward<F>(f_))
+            {}
+#else
+            task_object(F const& f_):
                 f(f_)
             {}
-#else
+
 #if defined BOOST_THREAD_USES_MOVE
             task_object(boost::rv<F>& f_):
                 f(boost::move(f_))
@@ -1736,17 +1749,29 @@
             task_base<void>
         {
             F f;
-            task_object(F const& f_):
+#ifndef BOOST_NO_RVALUE_REFERENCES
+            task_object(void(*f_)()):
                 f(f_)
             {}
-#ifndef BOOST_NO_RVALUE_REFERENCES
             task_object(F&& f_):
+              f(boost::forward<F>(f_))
+            {}
+#else
+            task_object(F const& f_):
                 f(f_)
             {}
-#else
 #if defined BOOST_THREAD_USES_MOVE
             task_object(boost::rv<F>& f_):
-                f(boost::move(f_))
+                f(boost::forward<F>(f_))
             {}
 #else
             task_object(boost::detail::thread_move_t<F> f_):
@@ -1779,6 +1804,7 @@
     template<typename R>
     class packaged_task
     {
+        typedef boost::shared_ptr<detail::task_base<R> > task_ptr;
         boost::shared_ptr<detail::task_base<R> > task;
         bool future_obtained;
 
@@ -1792,25 +1818,29 @@
         packaged_task& operator=(packaged_task&);// = delete;
 #endif // BOOST_NO_DELETED_FUNCTIONS
     public:
+        typedef R result_type;
         packaged_task():
             future_obtained(false)
         {}
 
         // construction and destruction
+
+#ifndef BOOST_NO_RVALUE_REFERENCES
+        explicit packaged_task(R(*f)()):
+            task(new detail::task_object<R,R(*)()>(f)),future_obtained(false)
+        {}
         template <class F>
-        explicit packaged_task(F const& f):
-            task(new detail::task_object<R,F>(f)),future_obtained(false)
+        explicit packaged_task(F&& f):
+            task(new detail::task_object<R,F>(boost::forward<F>(f))),future_obtained(false)
         {}
+#else
         explicit packaged_task(R(*f)()):
             task(new detail::task_object<R,R(*)()>(f)),future_obtained(false)
         {}
-
-#ifndef BOOST_NO_RVALUE_REFERENCES
         template <class F>
-        explicit packaged_task(F&& f):
+        explicit packaged_task(F const& f):
             task(new detail::task_object<R,F>(f)),future_obtained(false)
         {}
-#else
 #if defined BOOST_THREAD_USES_MOVE
         template <class F>
         explicit packaged_task(boost::rv<F>& f):