Boost logo

Boost Users :

Subject: Re: [Boost-users] problems with Boost.Thread on VS10
From: Vicente J. Botet Escriba (vicente.botet_at_[hidden])
Date: 2012-04-09 19:54:26


Le 10/04/12 01:24, Jeffrey Lee Hellrung, Jr. a écrit :
> On Mon, Apr 9, 2012 at 3:14 PM, Vicente J. Botet Escriba
> <vicente.botet_at_[hidden] <mailto:vicente.botet_at_[hidden]>> wrote:
>
>
> There are yet some problems on the Boost.Thread implementation or
> with the compilers implementation.
>
> When I want to pass functor, as in
>
> A a(5);
> boost::packaged_task<int> pt(a);
>
> the constructor used is packaged_task(F&& f) and I will expect
> packaged_task(F const& f) to be use for.
> Are my expectations correct?
>
>
> Well...no, apparently your expectations are not correct. But that's
> slightly beside the point. I think the correct fix here is to remove
> the packaged_task(F const &) overload entirely, since the
> packaged_task(F&&) overload already covers it (that's part of the
> entire design of "templated rvalue references", to capture both
> rvalues *and* lvalues). Then instantiate task_object with something
> like remove_cv< remove_reference<F>::type >::type, and use
> boost::forward<F>(f) to pass the function object down to the
> task_object constructor.
Yeah, this is the point. packaged_task(F const &) overload was not used
never, and task_object was instantiated as task_object<R,A&>. I have a
patch that seems to work (see below I have not used remove_cv yet, but I
agree it should be needed to take care of const functors).

The overload

         explicit packaged_task(R(*f)()):
             task(new
detail::task_object<R,R(*)()>(f)),future_obtained(false)
         {}

seems necessary because otherwise the task_object is instantiated with
<R,R()> which is not what we want.
Do you have an hint on how simplify this?
>
> The test futures/packaged_task/alloc_ctor_pass.cpp gives this context.
>
> Thanks for your patience and perseverance.
>
>
> And thank you for clarifying the issue for me!
>
>
Please, could you check the patch and see if there is something that can
be improved.

Thanks for all,
Vicente

iMac-de-Vicente-Botet-Escriba:trunk viboes$ svn diff boost/thread
libs/thread
Index: boost/thread/future.hpp
===================================================================
--- boost/thread/future.hpp (revision 77870)
+++ boost/thread/future.hpp (working copy)
@@ -19,6 +19,7 @@
  #include <boost/scoped_ptr.hpp>
  #include <boost/type_traits/is_fundamental.hpp>
  #include <boost/type_traits/is_convertible.hpp>
+#include <boost/type_traits/remove_reference.hpp>
  #include <boost/mpl/if.hpp>
  #include <boost/config.hpp>
  #include <boost/throw_exception.hpp>
@@ -1807,16 +1808,16 @@
          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)
- {}
  #ifndef BOOST_NO_RVALUE_REFERENCES
          template <class F>
          explicit packaged_task(F&& f):
- task(new
detail::task_object<R,F>(boost::forward<F>(f))),future_obtained(false)
+ task(new detail::task_object<R,typename
remove_reference<F>::type>(boost::forward<F>(f))),future_obtained(false)
          {}
  #else
+ template <class F>
+ explicit packaged_task(F const& f):
+ task(new detail::task_object<R,F>(f)),future_obtained(false)
+ {}
  #if defined BOOST_THREAD_USES_MOVE
          template <class F>
          explicit packaged_task(boost::rv<F>& f):
@@ -1831,29 +1832,30 @@
  #endif

  #if defined BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS
+#ifndef BOOST_NO_RVALUE_REFERENCES
          template <class F, class Allocator>
- packaged_task(boost::allocator_arg_t, Allocator a, const F& f)
+ packaged_task(boost::allocator_arg_t, Allocator a, F&& f)
          {
- typedef typename Allocator::template
rebind<detail::task_object<R,F> >::other A2;
+ typedef typename remove_reference<F>::type FR;
+ typedef typename Allocator::template
rebind<detail::task_object<R,FR> >::other A2;
            A2 a2(a);
            typedef thread_detail::allocator_destructor<A2> D;

- task = task_ptr(::new(a2.allocate(1))
detail::task_object<R,F>(f), D(a2, 1) );
- std::cout << __FILE__ ":"<<__LINE__<<std::endl;
+ task = task_ptr(::new(a2.allocate(1))
detail::task_object<R,FR>(boost::forward<F>(f)), D(a2, 1) );
            future_obtained = false;
          }
-#ifndef BOOST_NO_RVALUE_REFERENCES
+#else
          template <class F, class Allocator>
- packaged_task(boost::allocator_arg_t, Allocator a, F&& f)
+ packaged_task(boost::allocator_arg_t, Allocator a, const F& f)
          {
            typedef typename Allocator::template
rebind<detail::task_object<R,F> >::other A2;
            A2 a2(a);
            typedef thread_detail::allocator_destructor<A2> D;

- task = task_ptr(::new(a2.allocate(1))
detail::task_object<R,F>(boost::forward<F>(f)), D(a2, 1) );
+ task = task_ptr(::new(a2.allocate(1))
detail::task_object<R,F>(f), D(a2, 1) );
+ std::cout << __FILE__ ":"<<__LINE__<<std::endl;
            future_obtained = false;
          }
-#else
  #if defined BOOST_THREAD_USES_MOVE
          template <class F, class Allocator>
          packaged_task(boost::allocator_arg_t, Allocator a,
boost::rv<F>& f)



Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net